回答編集履歴

1

コード例追加

2017/06/14 23:57

投稿

mituha
mituha

スコア385

test CHANGED
@@ -23,3 +23,211 @@
23
23
 
24
24
 
25
25
  このように、WPFではモデルとUI部分を強力に分離して扱いやすくする機能が標準で用意されており、フレームワークとして問題ないのではないでしょうか?
26
+
27
+
28
+
29
+ ## コード例
30
+
31
+ 色々端折っていますが、参考までに。
32
+
33
+
34
+
35
+ ```
36
+
37
+ <Window x:Class="TestShape.MainWindow"
38
+
39
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
40
+
41
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
42
+
43
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
44
+
45
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
46
+
47
+ xmlns:local="clr-namespace:TestShape"
48
+
49
+ mc:Ignorable="d"
50
+
51
+ Title="MainWindow" Height="350" Width="525"
52
+
53
+ >
54
+
55
+ <Window.Resources>
56
+
57
+ <DataTemplate DataType="{x:Type local:ShapeModel}">
58
+
59
+ <Rectangle Width="100" Height="50"
60
+
61
+ Fill="Red"/>
62
+
63
+
64
+
65
+ </DataTemplate>
66
+
67
+ <DataTemplate DataType="{x:Type local:EllipseModel}">
68
+
69
+ <!--
70
+
71
+ <Ellipse Width="40" Height="40"
72
+
73
+ Fill="Blue"/>
74
+
75
+ -->
76
+
77
+ <Path Stroke="Black" StrokeThickness="1">
78
+
79
+ <Path.Data>
80
+
81
+ <EllipseGeometry RadiusX="20" RadiusY="20" />
82
+
83
+ </Path.Data>
84
+
85
+ </Path>
86
+
87
+ </DataTemplate>
88
+
89
+ </Window.Resources>
90
+
91
+ <ItemsControl ItemsSource="{Binding Shapes}">
92
+
93
+ <ItemsControl.ItemContainerStyle>
94
+
95
+ <Style>
96
+
97
+ <Setter Property="Canvas.Left" Value="{Binding X}" />
98
+
99
+ <Setter Property="Canvas.Top" Value="{Binding Y}" />
100
+
101
+ </Style>
102
+
103
+ </ItemsControl.ItemContainerStyle>
104
+
105
+ <ItemsControl.ItemsPanel>
106
+
107
+ <ItemsPanelTemplate>
108
+
109
+ <Canvas Background="AliceBlue"/>
110
+
111
+ </ItemsPanelTemplate>
112
+
113
+ </ItemsControl.ItemsPanel>
114
+
115
+ </ItemsControl>
116
+
117
+ </Window>
118
+
119
+ ```
120
+
121
+ XAML側(MainWindow.xaml)。Modelに合わせてDataTemplateを定義しています。
122
+
123
+ Pathは、Rectangle や Ellipse より、更に低レベルな描画用です。
124
+
125
+
126
+
127
+ ```
128
+
129
+ namespace TestShape
130
+
131
+ {
132
+
133
+ /// <summary>
134
+
135
+ /// MainWindow.xaml の相互作用ロジック
136
+
137
+ /// </summary>
138
+
139
+ public partial class MainWindow : Window
140
+
141
+ {
142
+
143
+ public MainWindow() {
144
+
145
+ InitializeComponent();
146
+
147
+
148
+
149
+
150
+
151
+ this.Shapes.Add(new ShapeModel() { X = 100, Y = 50 });
152
+
153
+ this.Shapes.Add(new EllipseModel() { X = 50, Y = 100 });
154
+
155
+
156
+
157
+ this.DataContext = this;
158
+
159
+ }
160
+
161
+
162
+
163
+
164
+
165
+ public ObservableCollection<ShapeModel> Shapes { get; } = new ObservableCollection<ShapeModel>();
166
+
167
+ }
168
+
169
+ }
170
+
171
+ ```
172
+
173
+ MainWindow.xaml.cs 側。
174
+
175
+ とりあえず、コンストラクタでモデルを突っ込んでいます。
176
+
177
+
178
+
179
+ ```
180
+
181
+ namespace TestShape
182
+
183
+ {
184
+
185
+ /// <summary>
186
+
187
+ /// TODO 通知可能なクラスにする
188
+
189
+ /// </summary>
190
+
191
+ public class ShapeModel
192
+
193
+ {
194
+
195
+ public int X { get; set; }
196
+
197
+ public int Y { get; set; }
198
+
199
+ }
200
+
201
+
202
+
203
+ public class EllipseModel: ShapeModel
204
+
205
+ {
206
+
207
+
208
+
209
+ }
210
+
211
+ }
212
+
213
+ ```
214
+
215
+ モデル側。都合の良い用に継承構造等を用意できます。
216
+
217
+ 実際にバインディングする場合、通知可能な構造が必要です。
218
+
219
+ 場合によってはVMを挟む等するが良いと思います。
220
+
221
+
222
+
223
+ マウスクリックによる操作や、D&D等は、`WPF Thumb リサイズ` 等でググれば例もあると思います。
224
+
225
+ すぐにコード書けなかったのでDataTemplateの実例までとします。
226
+
227
+
228
+
229
+
230
+
231
+
232
+
233
+