質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

Q&A

解決済

1回答

2974閲覧

ItemsControlのItemを値によってコントロールを変えたい。

Y...M

総合スコア18

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

0グッド

0クリップ

投稿2020/03/19 07:41

前提・実現したいこと

ItemsControlで複数のコントロールを表示したい。

バインドしているItemクラスのItemTypeプロパティの内容によって
表示する内容も変更したい。

発生している問題・エラーメッセージ

thumbを挟んでしか表現できない。
thumbを挟まずに、Itemの階層を減らしたい。
可能であれば、スタイルではなくDataTempleteのTriggerで定義したい。

該当のソースコード

<ItemsControl Name="items" ItemsSource="{Binding Items}" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Background="Black" Foreground="White"> <ItemsControl.ItemsPanel> <ItemsPanelTemplate> <Canvas/> </ItemsPanelTemplate> </ItemsControl.ItemsPanel> <ItemsControl.ItemTemplate> <DataTemplate> <Thumb IsHitTestVisible="False" Width="{Binding Width}" Height="{Binding Height}" Style="{StaticResource ItemStyle}"> </Thumb> </DataTemplate> </ItemsControl.ItemTemplate> <ItemsControl.ItemContainerStyle> <Style> <Setter Property="Canvas.Top" Value="{Binding Y}" /> <Setter Property="Canvas.Left" Value="{Binding X}" /> </Style> </ItemsControl.ItemContainerStyle> </ItemsControl>
<Style x:Key="ItemStyle" TargetType="Control"> <Style.Triggers> <DataTrigger Value="ItemA" Binding="{Binding ItemType}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate> <Line/> </ControlTemplate> </Setter.Value> </Setter> </DataTrigger> <DataTrigger Value="ItemB" Binding="{Binding ItemType}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate> <Rectangle /> </ControlTemplate> </Setter.Value> </Setter> </DataTrigger> </Style.Triggers> </Style>

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

ちょっと要望と違うのですが、各ItemTypeごとにクラスを分けてしまえばよいのではないでしょうか?(Triggerが手強かったので諦めただけですが^^;

文字数制限によりコード削除(編集履歴を参照)


追記

案1

バカバカしいが全パターンを入れておいて、Visibilityで切り替え(ボツでしょうねぇ)

xml

1<Window 2 x:Class="Questions248125.MainWindow" 3 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 4 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 5 xmlns:local="clr-namespace:Questions248125" 6 Width="800" 7 Height="450"> 8 <Grid> 9 <ItemsControl 10 Background="Black" 11 Foreground="White" 12 ItemsSource="{Binding Items}"> 13 <ItemsControl.Resources> 14 15 <DataTemplate DataType="{x:Type local:Item}"> 16 <Grid> 17 <Line 18 Name="Line" 19 Stroke="{Binding Brush}" 20 StrokeThickness="3" 21 X1="0" 22 X2="{Binding Width}" 23 Y1="0" 24 Y2="0" /> 25 <Rectangle 26 Name="Rectangle" 27 Width="{Binding Width}" 28 Height="{Binding Height}" 29 Fill="{Binding Brush}" /> 30 <Ellipse 31 Name="Ellipse" 32 Width="{Binding Width}" 33 Height="{Binding Height}" 34 Fill="{Binding Brush}" /> 35 </Grid> 36 <DataTemplate.Triggers> 37 <DataTrigger Binding="{Binding ItemType}" Value="Line"> 38 <DataTrigger.Setters> 39 <Setter TargetName="Line" Property="Visibility" Value="Visible" /> 40 <Setter TargetName="Rectangle" Property="Visibility" Value="Collapsed" /> 41 <Setter TargetName="Ellipse" Property="Visibility" Value="Collapsed" /> 42 </DataTrigger.Setters> 43 </DataTrigger> 44 <DataTrigger Binding="{Binding ItemType}" Value="Rectangle"> 45 <DataTrigger.Setters> 46 <Setter TargetName="Line" Property="Visibility" Value="Collapsed" /> 47 <Setter TargetName="Rectangle" Property="Visibility" Value="Visible" /> 48 <Setter TargetName="Ellipse" Property="Visibility" Value="Collapsed" /> 49 </DataTrigger.Setters> 50 </DataTrigger> 51 <DataTrigger Binding="{Binding ItemType}" Value="Ellipse"> 52 <DataTrigger.Setters> 53 <Setter TargetName="Line" Property="Visibility" Value="Collapsed" /> 54 <Setter TargetName="Rectangle" Property="Visibility" Value="Collapsed" /> 55 <Setter TargetName="Ellipse" Property="Visibility" Value="Visible" /> 56 </DataTrigger.Setters> 57 </DataTrigger> 58 </DataTemplate.Triggers> 59 </DataTemplate> 60 61 </ItemsControl.Resources> 62 <ItemsControl.ItemsPanel> 63 <ItemsPanelTemplate> 64 <Canvas /> 65 </ItemsPanelTemplate> 66 </ItemsControl.ItemsPanel> 67 <ItemsControl.ItemContainerStyle> 68 <Style> 69 <Setter Property="Canvas.Top" Value="{Binding Y}" /> 70 <Setter Property="Canvas.Left" Value="{Binding X}" /> 71 </Style> 72 </ItemsControl.ItemContainerStyle> 73 </ItemsControl> 74 75 <Button 76 HorizontalAlignment="Center" 77 VerticalAlignment="Top" 78 Click="Button_Click" 79 Content="ChangeShapes" /> 80 </Grid> 81</Window>

cs

1using System; 2using System.Collections.ObjectModel; 3using System.ComponentModel; 4using System.Runtime.CompilerServices; 5using System.Windows; 6using System.Windows.Media; 7 8namespace Questions248125 9{ 10 public enum ItemType { Line, Rectangle, Ellipse, } 11 12 public class Item : INotifyPropertyChanged 13 { 14 public int X { get; } 15 public int Y { get; } 16 public int Width { get; } 17 public int Height { get; } 18 public SolidColorBrush Brush { get; } 19 public ItemType ItemType { get => _ItemType; set => Set(ref _ItemType, value, null); } 20 public ItemType _ItemType; 21 22 private static readonly Random r = new Random(); 23 private static readonly Array types = Enum.GetValues(typeof(ItemType)); 24 25 public Item() 26 { 27 X = r.Next(700); 28 Y = r.Next(350); 29 Width = r.Next(400); 30 Height = r.Next(300); 31 Brush = new SolidColorBrush(Color.FromRgb((byte)r.Next(255), (byte)r.Next(255), (byte)r.Next(255))); 32 ItemType = (ItemType)types.GetValue(r.Next(types.Length)); 33 } 34 35 public void ChangeShape() => ItemType = (ItemType)types.GetValue(r.Next(types.Length)); 36 37 #region INotifyPropertyChanged 38 public event PropertyChangedEventHandler PropertyChanged; 39 protected bool Set<T>(ref T storage, T value, [CallerMemberName] string propertyName = null) 40 { 41 if(Equals(storage, value)) return false; 42 storage = value; 43 OnPropertyChanged(propertyName); 44 return true; 45 } 46 protected void OnPropertyChanged([CallerMemberName] string propertyName = null) 47 => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); 48 #endregion 49 } 50 51 public partial class MainWindow : Window 52 { 53 public ObservableCollection<Item> Items { get; } 54 55 public MainWindow() 56 { 57 InitializeComponent(); 58 59 DataContext = this; 60 Items = new ObservableCollection<Item> 61 { 62 new Item(), 63 new Item(), 64 new Item(), 65 new Item(), 66 new Item(), 67 }; 68 } 69 private void Button_Click(object sender, RoutedEventArgs e) 70 { 71 foreach(var item in Items) item.ChangeShape(); 72 } 73 } 74}

案2

1段間に挟まってしまうが、DataTemplate.TriggerControlTemplateを切り替える。

xml

1<Window 2 x:Class="Questions248125.MainWindow" 3 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 4 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 5 xmlns:local="clr-namespace:Questions248125" 6 Width="800" 7 Height="450"> 8 <Grid> 9 <ItemsControl 10 Background="Black" 11 Foreground="White" 12 ItemsSource="{Binding Items}"> 13 <ItemsControl.Resources> 14 <ControlTemplate x:Key="Line"> 15 <Line 16 Name="Line" 17 Stroke="{Binding Brush}" 18 StrokeThickness="3" 19 X1="0" 20 X2="{Binding Width}" 21 Y1="0" 22 Y2="0" /> 23 </ControlTemplate> 24 <ControlTemplate x:Key="Rectangle"> 25 <Rectangle 26 Name="Rectangle" 27 Width="{Binding Width}" 28 Height="{Binding Height}" 29 Fill="{Binding Brush}" /> 30 </ControlTemplate> 31 <ControlTemplate x:Key="Ellipse"> 32 <Ellipse 33 Name="Ellipse" 34 Width="{Binding Width}" 35 Height="{Binding Height}" 36 Fill="{Binding Brush}" /> 37 </ControlTemplate> 38 <DataTemplate DataType="{x:Type local:Item}"> 39 <Control Name="Control" /> 40 <DataTemplate.Triggers> 41 <DataTrigger Binding="{Binding ItemType}" Value="Line"> 42 <DataTrigger.Setters> 43 <Setter TargetName="Control" Property="Template" Value="{StaticResource Line}" /> 44 </DataTrigger.Setters> 45 </DataTrigger> 46 <DataTrigger Binding="{Binding ItemType}" Value="Rectangle"> 47 <DataTrigger.Setters> 48 <Setter TargetName="Control" Property="Template" Value="{StaticResource Rectangle}" /> 49 </DataTrigger.Setters> 50 </DataTrigger> 51 <DataTrigger Binding="{Binding ItemType}" Value="Ellipse"> 52 <DataTrigger.Setters> 53 <Setter TargetName="Control" Property="Template" Value="{StaticResource Ellipse}" /> 54 </DataTrigger.Setters> 55 </DataTrigger> 56 </DataTemplate.Triggers> 57 </DataTemplate> 58 59 </ItemsControl.Resources> 60 <ItemsControl.ItemsPanel> 61 <ItemsPanelTemplate> 62 <Canvas /> 63 </ItemsPanelTemplate> 64 </ItemsControl.ItemsPanel> 65 <ItemsControl.ItemContainerStyle> 66 <Style> 67 <Setter Property="Canvas.Top" Value="{Binding Y}" /> 68 <Setter Property="Canvas.Left" Value="{Binding X}" /> 69 </Style> 70 </ItemsControl.ItemContainerStyle> 71 </ItemsControl> 72 73 <Button 74 HorizontalAlignment="Center" 75 VerticalAlignment="Top" 76 Click="Button_Click" 77 Content="ChangeShapes" /> 78 </Grid> 79</Window>

C#コードは同じ

案3

いっそのことDependencyPropertyItemTypeを持った専用コントロールを作ってしまう。
これも方向性が違うのでコードは省略。

投稿2020/03/19 09:55

編集2023/07/21 09:01
TN8001

総合スコア9326

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Y...M

2020/03/23 00:05 編集

回答ありがとうございます。 やはり、継承させてそれぞれクラスを定義する方法が最善でしょうかね…。 以下のケースが想定されるため、継承ではなくタイプで判断しようとしていました。(後出しですみません…。) ・インスタンスは同じまま、別のタイプに変換し、見た目を変更する。  (既存の参照を残したままタイプを変更したいため)
Y...M

2020/03/23 08:07

複数案も検討いただきありがとうございます。 なかなか実現できる方法が見つからないということは、そもそもこの切り口が悪いのかもしれません。 根本から再度検討し直してみます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問