teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

2

見直しキャンペーン中

2023/07/21 09:01

投稿

TN8001
TN8001

スコア10111

answer CHANGED
@@ -1,259 +1,259 @@
1
- ちょっと要望と違うのですが、各ItemTypeごとにクラスを分けてしまえばよいのではないでしょうか?(Triggerが手強かったので諦めただけですが^^;
2
-
3
- 文字数制限によりコード削除(編集履歴を参照)
4
-
5
- ---
6
-
7
- 追記
8
-
9
- ## 案1
10
- バカバカしいが全パターンを入れておいて、`Visibility`で切り替え(ボツでしょうねぇ)
11
- ```xaml
12
- <Window
13
- x:Class="Questions248125.MainWindow"
14
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
15
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
16
- xmlns:local="clr-namespace:Questions248125"
17
- Width="800"
18
- Height="450">
19
- <Grid>
20
- <ItemsControl
21
- Background="Black"
22
- Foreground="White"
23
- ItemsSource="{Binding Items}">
24
- <ItemsControl.Resources>
25
-
26
- <DataTemplate DataType="{x:Type local:Item}">
27
- <Grid>
28
- <Line
29
- Name="Line"
30
- Stroke="{Binding Brush}"
31
- StrokeThickness="3"
32
- X1="0"
33
- X2="{Binding Width}"
34
- Y1="0"
35
- Y2="0" />
36
- <Rectangle
37
- Name="Rectangle"
38
- Width="{Binding Width}"
39
- Height="{Binding Height}"
40
- Fill="{Binding Brush}" />
41
- <Ellipse
42
- Name="Ellipse"
43
- Width="{Binding Width}"
44
- Height="{Binding Height}"
45
- Fill="{Binding Brush}" />
46
- </Grid>
47
- <DataTemplate.Triggers>
48
- <DataTrigger Binding="{Binding ItemType}" Value="Line">
49
- <DataTrigger.Setters>
50
- <Setter TargetName="Line" Property="Visibility" Value="Visible" />
51
- <Setter TargetName="Rectangle" Property="Visibility" Value="Collapsed" />
52
- <Setter TargetName="Ellipse" Property="Visibility" Value="Collapsed" />
53
- </DataTrigger.Setters>
54
- </DataTrigger>
55
- <DataTrigger Binding="{Binding ItemType}" Value="Rectangle">
56
- <DataTrigger.Setters>
57
- <Setter TargetName="Line" Property="Visibility" Value="Collapsed" />
58
- <Setter TargetName="Rectangle" Property="Visibility" Value="Visible" />
59
- <Setter TargetName="Ellipse" Property="Visibility" Value="Collapsed" />
60
- </DataTrigger.Setters>
61
- </DataTrigger>
62
- <DataTrigger Binding="{Binding ItemType}" Value="Ellipse">
63
- <DataTrigger.Setters>
64
- <Setter TargetName="Line" Property="Visibility" Value="Collapsed" />
65
- <Setter TargetName="Rectangle" Property="Visibility" Value="Collapsed" />
66
- <Setter TargetName="Ellipse" Property="Visibility" Value="Visible" />
67
- </DataTrigger.Setters>
68
- </DataTrigger>
69
- </DataTemplate.Triggers>
70
- </DataTemplate>
71
-
72
- </ItemsControl.Resources>
73
- <ItemsControl.ItemsPanel>
74
- <ItemsPanelTemplate>
75
- <Canvas />
76
- </ItemsPanelTemplate>
77
- </ItemsControl.ItemsPanel>
78
- <ItemsControl.ItemContainerStyle>
79
- <Style>
80
- <Setter Property="Canvas.Top" Value="{Binding Y}" />
81
- <Setter Property="Canvas.Left" Value="{Binding X}" />
82
- </Style>
83
- </ItemsControl.ItemContainerStyle>
84
- </ItemsControl>
85
-
86
- <Button
87
- HorizontalAlignment="Center"
88
- VerticalAlignment="Top"
89
- Click="Button_Click"
90
- Content="ChangeShapes" />
91
- </Grid>
92
- </Window>
93
- ```
94
-
95
- ```C#
96
- using System;
97
- using System.Collections.ObjectModel;
98
- using System.ComponentModel;
99
- using System.Runtime.CompilerServices;
100
- using System.Windows;
101
- using System.Windows.Media;
102
-
103
- namespace Questions248125
104
- {
105
- public enum ItemType { Line, Rectangle, Ellipse, }
106
-
107
- public class Item : INotifyPropertyChanged
108
- {
109
- public int X { get; }
110
- public int Y { get; }
111
- public int Width { get; }
112
- public int Height { get; }
113
- public SolidColorBrush Brush { get; }
114
- public ItemType ItemType { get => _ItemType; set => Set(ref _ItemType, value, null); }
115
- public ItemType _ItemType;
116
-
117
- private static readonly Random r = new Random();
118
- private static readonly Array types = Enum.GetValues(typeof(ItemType));
119
-
120
- public Item()
121
- {
122
- X = r.Next(700);
123
- Y = r.Next(350);
124
- Width = r.Next(400);
125
- Height = r.Next(300);
126
- Brush = new SolidColorBrush(Color.FromRgb((byte)r.Next(255), (byte)r.Next(255), (byte)r.Next(255)));
127
- ItemType = (ItemType)types.GetValue(r.Next(types.Length));
128
- }
129
-
130
- public void ChangeShape() => ItemType = (ItemType)types.GetValue(r.Next(types.Length));
131
-
132
- #region INotifyPropertyChanged
133
- public event PropertyChangedEventHandler PropertyChanged;
134
- protected bool Set<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
135
- {
136
- if(Equals(storage, value)) return false;
137
- storage = value;
138
- OnPropertyChanged(propertyName);
139
- return true;
140
- }
141
- protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
142
- => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
143
- #endregion
144
- }
145
-
146
- public partial class MainWindow : Window
147
- {
148
- public ObservableCollection<Item> Items { get; }
149
-
150
- public MainWindow()
151
- {
152
- InitializeComponent();
153
-
154
- DataContext = this;
155
- Items = new ObservableCollection<Item>
156
- {
157
- new Item(),
158
- new Item(),
159
- new Item(),
160
- new Item(),
161
- new Item(),
162
- };
163
- }
164
- private void Button_Click(object sender, RoutedEventArgs e)
165
- {
166
- foreach(var item in Items) item.ChangeShape();
167
- }
168
- }
169
- }
170
- ```
171
-
172
- ## 案2
173
- 1段間に挟まってしまうが、`DataTemplate.Trigger`で`ControlTemplate`を切り替える。
174
- ```xaml
175
- <Window
176
- x:Class="Questions248125.MainWindow"
177
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
178
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
179
- xmlns:local="clr-namespace:Questions248125"
180
- Width="800"
181
- Height="450">
182
- <Grid>
183
- <ItemsControl
184
- Background="Black"
185
- Foreground="White"
186
- ItemsSource="{Binding Items}">
187
- <ItemsControl.Resources>
188
- <ControlTemplate x:Key="Line">
189
- <Line
190
- Name="Line"
191
- Stroke="{Binding Brush}"
192
- StrokeThickness="3"
193
- X1="0"
194
- X2="{Binding Width}"
195
- Y1="0"
196
- Y2="0" />
197
- </ControlTemplate>
198
- <ControlTemplate x:Key="Rectangle">
199
- <Rectangle
200
- Name="Rectangle"
201
- Width="{Binding Width}"
202
- Height="{Binding Height}"
203
- Fill="{Binding Brush}" />
204
- </ControlTemplate>
205
- <ControlTemplate x:Key="Ellipse">
206
- <Ellipse
207
- Name="Ellipse"
208
- Width="{Binding Width}"
209
- Height="{Binding Height}"
210
- Fill="{Binding Brush}" />
211
- </ControlTemplate>
212
- <DataTemplate DataType="{x:Type local:Item}">
213
- <Control Name="Control" />
214
- <DataTemplate.Triggers>
215
- <DataTrigger Binding="{Binding ItemType}" Value="Line">
216
- <DataTrigger.Setters>
217
- <Setter TargetName="Control" Property="Template" Value="{StaticResource Line}" />
218
- </DataTrigger.Setters>
219
- </DataTrigger>
220
- <DataTrigger Binding="{Binding ItemType}" Value="Rectangle">
221
- <DataTrigger.Setters>
222
- <Setter TargetName="Control" Property="Template" Value="{StaticResource Rectangle}" />
223
- </DataTrigger.Setters>
224
- </DataTrigger>
225
- <DataTrigger Binding="{Binding ItemType}" Value="Ellipse">
226
- <DataTrigger.Setters>
227
- <Setter TargetName="Control" Property="Template" Value="{StaticResource Ellipse}" />
228
- </DataTrigger.Setters>
229
- </DataTrigger>
230
- </DataTemplate.Triggers>
231
- </DataTemplate>
232
-
233
- </ItemsControl.Resources>
234
- <ItemsControl.ItemsPanel>
235
- <ItemsPanelTemplate>
236
- <Canvas />
237
- </ItemsPanelTemplate>
238
- </ItemsControl.ItemsPanel>
239
- <ItemsControl.ItemContainerStyle>
240
- <Style>
241
- <Setter Property="Canvas.Top" Value="{Binding Y}" />
242
- <Setter Property="Canvas.Left" Value="{Binding X}" />
243
- </Style>
244
- </ItemsControl.ItemContainerStyle>
245
- </ItemsControl>
246
-
247
- <Button
248
- HorizontalAlignment="Center"
249
- VerticalAlignment="Top"
250
- Click="Button_Click"
251
- Content="ChangeShapes" />
252
- </Grid>
253
- </Window>
254
- ```
255
- C#コードは同じ
256
-
257
- ## 案3
258
- いっそのこと`DependencyProperty`で`ItemType`を持った専用コントロールを作ってしまう。
1
+ ちょっと要望と違うのですが、各ItemTypeごとにクラスを分けてしまえばよいのではないでしょうか?(Triggerが手強かったので諦めただけですが^^;
2
+
3
+ 文字数制限によりコード削除(編集履歴を参照)
4
+
5
+ ---
6
+
7
+ 追記
8
+
9
+ ## 案1
10
+ バカバカしいが全パターンを入れておいて、`Visibility`で切り替え(ボツでしょうねぇ)
11
+ ```xml
12
+ <Window
13
+ x:Class="Questions248125.MainWindow"
14
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
15
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
16
+ xmlns:local="clr-namespace:Questions248125"
17
+ Width="800"
18
+ Height="450">
19
+ <Grid>
20
+ <ItemsControl
21
+ Background="Black"
22
+ Foreground="White"
23
+ ItemsSource="{Binding Items}">
24
+ <ItemsControl.Resources>
25
+
26
+ <DataTemplate DataType="{x:Type local:Item}">
27
+ <Grid>
28
+ <Line
29
+ Name="Line"
30
+ Stroke="{Binding Brush}"
31
+ StrokeThickness="3"
32
+ X1="0"
33
+ X2="{Binding Width}"
34
+ Y1="0"
35
+ Y2="0" />
36
+ <Rectangle
37
+ Name="Rectangle"
38
+ Width="{Binding Width}"
39
+ Height="{Binding Height}"
40
+ Fill="{Binding Brush}" />
41
+ <Ellipse
42
+ Name="Ellipse"
43
+ Width="{Binding Width}"
44
+ Height="{Binding Height}"
45
+ Fill="{Binding Brush}" />
46
+ </Grid>
47
+ <DataTemplate.Triggers>
48
+ <DataTrigger Binding="{Binding ItemType}" Value="Line">
49
+ <DataTrigger.Setters>
50
+ <Setter TargetName="Line" Property="Visibility" Value="Visible" />
51
+ <Setter TargetName="Rectangle" Property="Visibility" Value="Collapsed" />
52
+ <Setter TargetName="Ellipse" Property="Visibility" Value="Collapsed" />
53
+ </DataTrigger.Setters>
54
+ </DataTrigger>
55
+ <DataTrigger Binding="{Binding ItemType}" Value="Rectangle">
56
+ <DataTrigger.Setters>
57
+ <Setter TargetName="Line" Property="Visibility" Value="Collapsed" />
58
+ <Setter TargetName="Rectangle" Property="Visibility" Value="Visible" />
59
+ <Setter TargetName="Ellipse" Property="Visibility" Value="Collapsed" />
60
+ </DataTrigger.Setters>
61
+ </DataTrigger>
62
+ <DataTrigger Binding="{Binding ItemType}" Value="Ellipse">
63
+ <DataTrigger.Setters>
64
+ <Setter TargetName="Line" Property="Visibility" Value="Collapsed" />
65
+ <Setter TargetName="Rectangle" Property="Visibility" Value="Collapsed" />
66
+ <Setter TargetName="Ellipse" Property="Visibility" Value="Visible" />
67
+ </DataTrigger.Setters>
68
+ </DataTrigger>
69
+ </DataTemplate.Triggers>
70
+ </DataTemplate>
71
+
72
+ </ItemsControl.Resources>
73
+ <ItemsControl.ItemsPanel>
74
+ <ItemsPanelTemplate>
75
+ <Canvas />
76
+ </ItemsPanelTemplate>
77
+ </ItemsControl.ItemsPanel>
78
+ <ItemsControl.ItemContainerStyle>
79
+ <Style>
80
+ <Setter Property="Canvas.Top" Value="{Binding Y}" />
81
+ <Setter Property="Canvas.Left" Value="{Binding X}" />
82
+ </Style>
83
+ </ItemsControl.ItemContainerStyle>
84
+ </ItemsControl>
85
+
86
+ <Button
87
+ HorizontalAlignment="Center"
88
+ VerticalAlignment="Top"
89
+ Click="Button_Click"
90
+ Content="ChangeShapes" />
91
+ </Grid>
92
+ </Window>
93
+ ```
94
+
95
+ ```cs
96
+ using System;
97
+ using System.Collections.ObjectModel;
98
+ using System.ComponentModel;
99
+ using System.Runtime.CompilerServices;
100
+ using System.Windows;
101
+ using System.Windows.Media;
102
+
103
+ namespace Questions248125
104
+ {
105
+ public enum ItemType { Line, Rectangle, Ellipse, }
106
+
107
+ public class Item : INotifyPropertyChanged
108
+ {
109
+ public int X { get; }
110
+ public int Y { get; }
111
+ public int Width { get; }
112
+ public int Height { get; }
113
+ public SolidColorBrush Brush { get; }
114
+ public ItemType ItemType { get => _ItemType; set => Set(ref _ItemType, value, null); }
115
+ public ItemType _ItemType;
116
+
117
+ private static readonly Random r = new Random();
118
+ private static readonly Array types = Enum.GetValues(typeof(ItemType));
119
+
120
+ public Item()
121
+ {
122
+ X = r.Next(700);
123
+ Y = r.Next(350);
124
+ Width = r.Next(400);
125
+ Height = r.Next(300);
126
+ Brush = new SolidColorBrush(Color.FromRgb((byte)r.Next(255), (byte)r.Next(255), (byte)r.Next(255)));
127
+ ItemType = (ItemType)types.GetValue(r.Next(types.Length));
128
+ }
129
+
130
+ public void ChangeShape() => ItemType = (ItemType)types.GetValue(r.Next(types.Length));
131
+
132
+ #region INotifyPropertyChanged
133
+ public event PropertyChangedEventHandler PropertyChanged;
134
+ protected bool Set<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
135
+ {
136
+ if(Equals(storage, value)) return false;
137
+ storage = value;
138
+ OnPropertyChanged(propertyName);
139
+ return true;
140
+ }
141
+ protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
142
+ => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
143
+ #endregion
144
+ }
145
+
146
+ public partial class MainWindow : Window
147
+ {
148
+ public ObservableCollection<Item> Items { get; }
149
+
150
+ public MainWindow()
151
+ {
152
+ InitializeComponent();
153
+
154
+ DataContext = this;
155
+ Items = new ObservableCollection<Item>
156
+ {
157
+ new Item(),
158
+ new Item(),
159
+ new Item(),
160
+ new Item(),
161
+ new Item(),
162
+ };
163
+ }
164
+ private void Button_Click(object sender, RoutedEventArgs e)
165
+ {
166
+ foreach(var item in Items) item.ChangeShape();
167
+ }
168
+ }
169
+ }
170
+ ```
171
+
172
+ ## 案2
173
+ 1段間に挟まってしまうが、`DataTemplate.Trigger`で`ControlTemplate`を切り替える。
174
+ ```xml
175
+ <Window
176
+ x:Class="Questions248125.MainWindow"
177
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
178
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
179
+ xmlns:local="clr-namespace:Questions248125"
180
+ Width="800"
181
+ Height="450">
182
+ <Grid>
183
+ <ItemsControl
184
+ Background="Black"
185
+ Foreground="White"
186
+ ItemsSource="{Binding Items}">
187
+ <ItemsControl.Resources>
188
+ <ControlTemplate x:Key="Line">
189
+ <Line
190
+ Name="Line"
191
+ Stroke="{Binding Brush}"
192
+ StrokeThickness="3"
193
+ X1="0"
194
+ X2="{Binding Width}"
195
+ Y1="0"
196
+ Y2="0" />
197
+ </ControlTemplate>
198
+ <ControlTemplate x:Key="Rectangle">
199
+ <Rectangle
200
+ Name="Rectangle"
201
+ Width="{Binding Width}"
202
+ Height="{Binding Height}"
203
+ Fill="{Binding Brush}" />
204
+ </ControlTemplate>
205
+ <ControlTemplate x:Key="Ellipse">
206
+ <Ellipse
207
+ Name="Ellipse"
208
+ Width="{Binding Width}"
209
+ Height="{Binding Height}"
210
+ Fill="{Binding Brush}" />
211
+ </ControlTemplate>
212
+ <DataTemplate DataType="{x:Type local:Item}">
213
+ <Control Name="Control" />
214
+ <DataTemplate.Triggers>
215
+ <DataTrigger Binding="{Binding ItemType}" Value="Line">
216
+ <DataTrigger.Setters>
217
+ <Setter TargetName="Control" Property="Template" Value="{StaticResource Line}" />
218
+ </DataTrigger.Setters>
219
+ </DataTrigger>
220
+ <DataTrigger Binding="{Binding ItemType}" Value="Rectangle">
221
+ <DataTrigger.Setters>
222
+ <Setter TargetName="Control" Property="Template" Value="{StaticResource Rectangle}" />
223
+ </DataTrigger.Setters>
224
+ </DataTrigger>
225
+ <DataTrigger Binding="{Binding ItemType}" Value="Ellipse">
226
+ <DataTrigger.Setters>
227
+ <Setter TargetName="Control" Property="Template" Value="{StaticResource Ellipse}" />
228
+ </DataTrigger.Setters>
229
+ </DataTrigger>
230
+ </DataTemplate.Triggers>
231
+ </DataTemplate>
232
+
233
+ </ItemsControl.Resources>
234
+ <ItemsControl.ItemsPanel>
235
+ <ItemsPanelTemplate>
236
+ <Canvas />
237
+ </ItemsPanelTemplate>
238
+ </ItemsControl.ItemsPanel>
239
+ <ItemsControl.ItemContainerStyle>
240
+ <Style>
241
+ <Setter Property="Canvas.Top" Value="{Binding Y}" />
242
+ <Setter Property="Canvas.Left" Value="{Binding X}" />
243
+ </Style>
244
+ </ItemsControl.ItemContainerStyle>
245
+ </ItemsControl>
246
+
247
+ <Button
248
+ HorizontalAlignment="Center"
249
+ VerticalAlignment="Top"
250
+ Click="Button_Click"
251
+ Content="ChangeShapes" />
252
+ </Grid>
253
+ </Window>
254
+ ```
255
+ C#コードは同じ
256
+
257
+ ## 案3
258
+ いっそのこと`DependencyProperty`で`ItemType`を持った専用コントロールを作ってしまう。
259
259
  これも方向性が違うのでコードは省略。

1

追記

2020/03/23 02:05

投稿

TN8001
TN8001

スコア10111

answer CHANGED
@@ -1,12 +1,19 @@
1
- ちょっと要望と違うのですが、各`ItemType`ごとにクラスを分けてしまえばよいのではないでしょうか?(Triggerが手強かったので諦めただけですが^^;
1
+ ちょっと要望と違うのですが、各ItemTypeごとにクラスを分けてしまえばよいのではないでしょうか?(Triggerが手強かったので諦めただけですが^^;
2
2
 
3
+ 文字数制限によりコード削除(編集履歴を参照)
4
+
5
+ ---
6
+
7
+ 追記
8
+
9
+ ## 案1
10
+ バカバカしいが全パターンを入れておいて、`Visibility`で切り替え(ボツでしょうねぇ)
3
11
  ```xaml
4
12
  <Window
5
13
  x:Class="Questions248125.MainWindow"
6
14
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
7
15
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
8
16
  xmlns:local="clr-namespace:Questions248125"
9
- Title="MainWindow"
10
17
  Width="800"
11
18
  Height="450">
12
19
  <Grid>
@@ -16,29 +23,52 @@
16
23
  ItemsSource="{Binding Items}">
17
24
  <ItemsControl.Resources>
18
25
 
19
- <DataTemplate DataType="{x:Type local:Line}">
26
+ <DataTemplate DataType="{x:Type local:Item}">
27
+ <Grid>
20
- <Line
28
+ <Line
29
+ Name="Line"
21
- Stroke="{Binding Brush}"
30
+ Stroke="{Binding Brush}"
22
- StrokeThickness="3"
31
+ StrokeThickness="3"
23
- X1="0"
32
+ X1="0"
24
- X2="{Binding Width}"
33
+ X2="{Binding Width}"
25
- Y1="0"
34
+ Y1="0"
26
- Y2="0" />
35
+ Y2="0" />
36
+ <Rectangle
37
+ Name="Rectangle"
38
+ Width="{Binding Width}"
39
+ Height="{Binding Height}"
40
+ Fill="{Binding Brush}" />
41
+ <Ellipse
42
+ Name="Ellipse"
43
+ Width="{Binding Width}"
44
+ Height="{Binding Height}"
45
+ Fill="{Binding Brush}" />
46
+ </Grid>
47
+ <DataTemplate.Triggers>
48
+ <DataTrigger Binding="{Binding ItemType}" Value="Line">
49
+ <DataTrigger.Setters>
50
+ <Setter TargetName="Line" Property="Visibility" Value="Visible" />
51
+ <Setter TargetName="Rectangle" Property="Visibility" Value="Collapsed" />
52
+ <Setter TargetName="Ellipse" Property="Visibility" Value="Collapsed" />
53
+ </DataTrigger.Setters>
54
+ </DataTrigger>
55
+ <DataTrigger Binding="{Binding ItemType}" Value="Rectangle">
56
+ <DataTrigger.Setters>
57
+ <Setter TargetName="Line" Property="Visibility" Value="Collapsed" />
58
+ <Setter TargetName="Rectangle" Property="Visibility" Value="Visible" />
59
+ <Setter TargetName="Ellipse" Property="Visibility" Value="Collapsed" />
60
+ </DataTrigger.Setters>
61
+ </DataTrigger>
62
+ <DataTrigger Binding="{Binding ItemType}" Value="Ellipse">
63
+ <DataTrigger.Setters>
64
+ <Setter TargetName="Line" Property="Visibility" Value="Collapsed" />
65
+ <Setter TargetName="Rectangle" Property="Visibility" Value="Collapsed" />
66
+ <Setter TargetName="Ellipse" Property="Visibility" Value="Visible" />
67
+ </DataTrigger.Setters>
68
+ </DataTrigger>
69
+ </DataTemplate.Triggers>
27
70
  </DataTemplate>
28
71
 
29
- <DataTemplate DataType="{x:Type local:Rectangle}">
30
- <Rectangle
31
- Width="{Binding Width}"
32
- Height="{Binding Height}"
33
- Fill="{Binding Brush}" />
34
- </DataTemplate>
35
-
36
- <DataTemplate DataType="{x:Type local:Ellipse}">
37
- <Ellipse
38
- Width="{Binding Width}"
39
- Height="{Binding Height}"
40
- Fill="{Binding Brush}" />
41
- </DataTemplate>
42
72
  </ItemsControl.Resources>
43
73
  <ItemsControl.ItemsPanel>
44
74
  <ItemsPanelTemplate>
@@ -54,11 +84,10 @@
54
84
  </ItemsControl>
55
85
 
56
86
  <Button
57
- Width="80"
58
87
  HorizontalAlignment="Center"
59
88
  VerticalAlignment="Top"
60
89
  Click="Button_Click"
61
- Content="Add" />
90
+ Content="ChangeShapes" />
62
91
  </Grid>
63
92
  </Window>
64
93
  ```
@@ -66,23 +95,28 @@
66
95
  ```C#
67
96
  using System;
68
97
  using System.Collections.ObjectModel;
98
+ using System.ComponentModel;
99
+ using System.Runtime.CompilerServices;
69
100
  using System.Windows;
70
101
  using System.Windows.Media;
71
102
 
72
103
  namespace Questions248125
73
104
  {
105
+ public enum ItemType { Line, Rectangle, Ellipse, }
106
+
74
- public class Line : Item { }
107
+ public class Item : INotifyPropertyChanged
75
- public class Rectangle : Item { }
76
- public class Ellipse : Item { }
77
- public class Item
78
108
  {
79
109
  public int X { get; }
80
110
  public int Y { get; }
81
111
  public int Width { get; }
82
112
  public int Height { get; }
83
113
  public SolidColorBrush Brush { get; }
114
+ public ItemType ItemType { get => _ItemType; set => Set(ref _ItemType, value, null); }
115
+ public ItemType _ItemType;
84
116
 
85
117
  private static readonly Random r = new Random();
118
+ private static readonly Array types = Enum.GetValues(typeof(ItemType));
119
+
86
120
  public Item()
87
121
  {
88
122
  X = r.Next(700);
@@ -90,7 +124,23 @@
90
124
  Width = r.Next(400);
91
125
  Height = r.Next(300);
92
126
  Brush = new SolidColorBrush(Color.FromRgb((byte)r.Next(255), (byte)r.Next(255), (byte)r.Next(255)));
127
+ ItemType = (ItemType)types.GetValue(r.Next(types.Length));
93
128
  }
129
+
130
+ public void ChangeShape() => ItemType = (ItemType)types.GetValue(r.Next(types.Length));
131
+
132
+ #region INotifyPropertyChanged
133
+ public event PropertyChangedEventHandler PropertyChanged;
134
+ protected bool Set<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
135
+ {
136
+ if(Equals(storage, value)) return false;
137
+ storage = value;
138
+ OnPropertyChanged(propertyName);
139
+ return true;
140
+ }
141
+ protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
142
+ => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
143
+ #endregion
94
144
  }
95
145
 
96
146
  public partial class MainWindow : Window
@@ -104,20 +154,106 @@
104
154
  DataContext = this;
105
155
  Items = new ObservableCollection<Item>
106
156
  {
107
- new Line(),
157
+ new Item(),
108
- new Rectangle(),
109
- new Ellipse(),
158
+ new Item(),
159
+ new Item(),
160
+ new Item(),
161
+ new Item(),
110
162
  };
111
163
  }
112
164
  private void Button_Click(object sender, RoutedEventArgs e)
113
165
  {
114
- switch(new Random().Next(3))
115
- {
116
- case 0: Items.Add(new Line()); break;
117
- case 1: Items.Add(new Rectangle()); break;
166
+ foreach(var item in Items) item.ChangeShape();
118
- case 2: Items.Add(new Ellipse()); break;
119
- }
120
167
  }
121
168
  }
122
169
  }
123
- ```
170
+ ```
171
+
172
+ ## 案2
173
+ 1段間に挟まってしまうが、`DataTemplate.Trigger`で`ControlTemplate`を切り替える。
174
+ ```xaml
175
+ <Window
176
+ x:Class="Questions248125.MainWindow"
177
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
178
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
179
+ xmlns:local="clr-namespace:Questions248125"
180
+ Width="800"
181
+ Height="450">
182
+ <Grid>
183
+ <ItemsControl
184
+ Background="Black"
185
+ Foreground="White"
186
+ ItemsSource="{Binding Items}">
187
+ <ItemsControl.Resources>
188
+ <ControlTemplate x:Key="Line">
189
+ <Line
190
+ Name="Line"
191
+ Stroke="{Binding Brush}"
192
+ StrokeThickness="3"
193
+ X1="0"
194
+ X2="{Binding Width}"
195
+ Y1="0"
196
+ Y2="0" />
197
+ </ControlTemplate>
198
+ <ControlTemplate x:Key="Rectangle">
199
+ <Rectangle
200
+ Name="Rectangle"
201
+ Width="{Binding Width}"
202
+ Height="{Binding Height}"
203
+ Fill="{Binding Brush}" />
204
+ </ControlTemplate>
205
+ <ControlTemplate x:Key="Ellipse">
206
+ <Ellipse
207
+ Name="Ellipse"
208
+ Width="{Binding Width}"
209
+ Height="{Binding Height}"
210
+ Fill="{Binding Brush}" />
211
+ </ControlTemplate>
212
+ <DataTemplate DataType="{x:Type local:Item}">
213
+ <Control Name="Control" />
214
+ <DataTemplate.Triggers>
215
+ <DataTrigger Binding="{Binding ItemType}" Value="Line">
216
+ <DataTrigger.Setters>
217
+ <Setter TargetName="Control" Property="Template" Value="{StaticResource Line}" />
218
+ </DataTrigger.Setters>
219
+ </DataTrigger>
220
+ <DataTrigger Binding="{Binding ItemType}" Value="Rectangle">
221
+ <DataTrigger.Setters>
222
+ <Setter TargetName="Control" Property="Template" Value="{StaticResource Rectangle}" />
223
+ </DataTrigger.Setters>
224
+ </DataTrigger>
225
+ <DataTrigger Binding="{Binding ItemType}" Value="Ellipse">
226
+ <DataTrigger.Setters>
227
+ <Setter TargetName="Control" Property="Template" Value="{StaticResource Ellipse}" />
228
+ </DataTrigger.Setters>
229
+ </DataTrigger>
230
+ </DataTemplate.Triggers>
231
+ </DataTemplate>
232
+
233
+ </ItemsControl.Resources>
234
+ <ItemsControl.ItemsPanel>
235
+ <ItemsPanelTemplate>
236
+ <Canvas />
237
+ </ItemsPanelTemplate>
238
+ </ItemsControl.ItemsPanel>
239
+ <ItemsControl.ItemContainerStyle>
240
+ <Style>
241
+ <Setter Property="Canvas.Top" Value="{Binding Y}" />
242
+ <Setter Property="Canvas.Left" Value="{Binding X}" />
243
+ </Style>
244
+ </ItemsControl.ItemContainerStyle>
245
+ </ItemsControl>
246
+
247
+ <Button
248
+ HorizontalAlignment="Center"
249
+ VerticalAlignment="Top"
250
+ Click="Button_Click"
251
+ Content="ChangeShapes" />
252
+ </Grid>
253
+ </Window>
254
+ ```
255
+ C#コードは同じ
256
+
257
+ ## 案3
258
+ いっそのこと`DependencyProperty`で`ItemType`を持った専用コントロールを作ってしまう。
259
+ これも方向性が違うのでコードは省略。