ちょっと要望と違うのですが、各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.Trigger
でControlTemplate
を切り替える。
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
いっそのことDependencyProperty
でItemType
を持った専用コントロールを作ってしまう。
これも方向性が違うのでコードは省略。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/03/23 00:05 編集
2020/03/23 08:07