やりたいこと
ItemsControlを使ったコントロールの動的配置の際ScrollViewerが出ないのでなんとか出したい。
追記:この質問の趣旨ですが、WPFで動的にコントロールを追加するCodeを上手く動かす事が出来ず、ちょっと邪道だけどたまたま見つけたCodeで何とかできないか模索したものです。結果的に自己解決したのでそれも投稿しました。
個人的にアプリ開発をしています。
最近出したもの:リンク内容
実現したこと
UserControl を動的に生成して任意の座標に配置したい
上記のコードを書き換えまして、動的なコントロールの配置までは実現できました。しかしScrollViewerは出てくれません。ScrollViewerを配置して動かそうとするとControlの方が非表示になってしまいます。
追記:このリンク先のCode自体はどっちかというとTwitter上の「WPFじゃ○○が出来ない~」という声に対してokazuki氏が反応されたモノのようで、あまり通常のコントロール配置には適していないのではないかと思われます。
現状のコード(XAML)
XAML
1<Window 2 x:Class="PureWpf.MainWindow" 3 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 4 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 5 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 6 xmlns:local="clr-namespace:PureWpf" 7 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 8 Title="MainWindow" 9 Width="800" 10 Height="450" 11 mc:Ignorable="d"> 12 <Window.DataContext> 13 <local:MainWindowViewModel /> 14 </Window.DataContext> 15 <Grid VerticalAlignment="Top" ScrollViewer.CanContentScroll="True"> 16 <ScrollViewer VerticalScrollBarVisibility="Auto"/> 17 <Button Command="{Binding AddCommand}" Content="Add" Width="100" Height="50" /> 18 19 20 21 <ItemsControl Grid.Row="1" ItemsSource="{Binding Items}"> 22 23 <ItemsControl.ItemsPanel> 24 <!-- 要素の並びは Canvas で好きな座標に出せるようにする --> 25 <ItemsPanelTemplate> 26 27 28 <Canvas ScrollViewer.CanContentScroll="True" > 29 30 31 </Canvas> 32 33 34 </ItemsPanelTemplate> 35 36 </ItemsControl.ItemsPanel> 37 38 <ItemsControl.ItemTemplate> 39 40 <DataTemplate DataType="local:Item"> 41 <!-- ここに表示したい UserControl を設定する。今回は別途作るのがめんどいので WPF のコントロールを直接並べてます --> 42 <local:ParaSelector 43 Width="400" 44 Height="50" 45 Margin="10,-20,280,640" 46 > 47 48 </local:ParaSelector> 49 </DataTemplate> 50 </ItemsControl.ItemTemplate> 51 <ItemsControl.ItemContainerStyle> 52 <!-- Canvas 上での表示位置の設定は Canvas に直接乗るコンテナに指定 --> 53 <Style TargetType="ContentPresenter"> 54 <Setter Property="Canvas.Top" Value="{Binding Y}" /> 55 <Setter Property="Canvas.Left" Value="{Binding X}" /> 56 </Style> 57 </ItemsControl.ItemContainerStyle> 58 </ItemsControl> 59 60 61 62 </Grid> 63 64</Window> 65
コードビハインド(CS)
CS
1using Prism.Commands; 2using Prism.Mvvm; 3using System; 4using System.Collections.ObjectModel; 5 6namespace PureWpf 7{ 8 public class MainWindowViewModel : BindableBase 9 { 10 11 public ObservableCollection<Item> Items { get; } = new(); 12 13 private DelegateCommand _addCommand; 14 public DelegateCommand AddCommand => _addCommand ??= new(AddExecute); 15 16 int TOPCh =0; 17 int LeftCh = 0; 18 // 表示位置をランダムにするための Random クラス 19 private Random Random { get; } = new(); 20 private void AddExecute() 21 { 22 // ランダムな位置に、とりあえず現在時間の文字列を出すようなデータを作る 23 24 for (int i = 3; i > 0; i--) 25 { 26 Items.Add(new(TOPCh =0 , LeftCh+=30)); 27 } 28 29 30 } 31 32 } 33} 34 35
出力結果
見切れたときにScrollViewerが出てくれないと困るので何か方法をご教授願います。
前提条件として自作のカスタムコントロールを使用しています。
XAML
1<UserControl x:Class="PureWpf.ParaSelector" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 5 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 6 xmlns:local="clr-namespace:PureWpf" 7 mc:Ignorable="d" 8 d:DesignHeight="450" d:DesignWidth="800"> 9 <Grid> 10 11 <TextBox x:Name="ArgumentEditor" Margin="100,3,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="380"/> 12 13 <RadioButton 14 GroupName="SelectorGroup" Content="" Name="SlectorRadio" HorizontalAlignment="Left" Margin="0,5,0,0" VerticalAlignment="Top"/> 15 16 17 <ContentControl Name="SelectorLabelCon"> 18 <TextBlock 19 Name="ParamLabel" 20 TextWrapping="Wrap" 21 Width="80" 22 23 HorizontalAlignment="Left" 24 Text="パラメータ名" Margin="15,3,0,0"/> 25 </ContentControl> 26 </Grid> 27</UserControl> 28
試したこと
https://stackoverflow-com.translate.goog/questions/2028459/wpf-itemscontrol-with-scrollbar-scrollviewer?_x_tr_sl=en&_x_tr_tl=ja&_x_tr_hl=ja&_x_tr_pto=sc の2番目の回答などは試しました。既存のXAMLに組み込む形で試したものの、コントロールが追加されませんでした(実際は追加されているがホストされたコントロールにより非表示になっている)。
ItemsControl.ItemsPaneを <ItemsControl.Template>に置き換えるなどしました。
XAML
1<Window 2 x:Class="PureWpf.MainWindow" 3 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 4 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 5 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 6 xmlns:local="clr-namespace:PureWpf" 7 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 8 Title="MainWindow" 9 Width="800" 10 Height="450" 11 mc:Ignorable="d"> 12 <Window.DataContext> 13 <local:MainWindowViewModel /> 14 </Window.DataContext> 15 <Grid VerticalAlignment="Top" ScrollViewer.CanContentScroll="True"> 16 <ScrollViewer VerticalScrollBarVisibility="Auto"/> 17 <Button Command="{Binding AddCommand}" Content="Add" Width="100" Height="50" /> 18 19 20 21 <ItemsControl Grid.Row="1" ItemsSource="{Binding Items}"> 22 23 24 <ItemsControl.Template> 25 <!-- 要素の並びは Canvas で好きな座標に出せるようにする --> 26 <ControlTemplate> 27 28 <ScrollViewer> 29 <Canvas/> 30 </ScrollViewer> 31 32 33 34 </ControlTemplate> 35 36 </ItemsControl.Template> 37 38 <ItemsControl.ItemTemplate> 39 40 <DataTemplate DataType="local:Item"> 41 <!-- ここに表示したい UserControl を設定する。今回は別途作るのがめんどいので WPF のコントロールを直接並べてます --> 42 <local:ParaSelector 43 Width="400" 44 Height="50" 45 Margin="10,-20,280,640" 46 > 47 48 </local:ParaSelector> 49 </DataTemplate> 50 </ItemsControl.ItemTemplate> 51 <ItemsControl.ItemContainerStyle> 52 <!-- Canvas 上での表示位置の設定は Canvas に直接乗るコンテナに指定 --> 53 <Style TargetType="ContentPresenter"> 54 <Setter Property="Canvas.Top" Value="{Binding Y}" /> 55 <Setter Property="Canvas.Left" Value="{Binding X}" /> 56 </Style> 57 </ItemsControl.ItemContainerStyle> 58 59 </ItemsControl> 60 61 62 63 </Grid> 64 65</Window> 66
補足情報(FW/ツールのバージョンなど)
Visual Studio 2022を使用しています。.net7で開発しています。

回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2023/02/18 07:12
2023/02/18 07:57
2023/02/18 10:01
2023/02/18 11:38
2023/02/19 09:30
2023/02/21 00:01
2023/02/21 03:46