回答編集履歴

2

見直しキャンペーン中

2023/07/28 13:54

投稿

TN8001
TN8001

スコア9350

test CHANGED
@@ -1,291 +1,146 @@
1
1
  まず[Bitmap クラス (System.Drawing) | Microsoft Docs](https://docs.microsoft.com/ja-jp/dotnet/api/system.drawing.bitmap) は、Windows Formsのクラスなので基本的にはWPFで使えません(使う方法はありますが)
2
2
 
3
3
 
4
-
5
-
6
-
7
4
  Windows FormsではGDI/GDI+での描画でしたが、WPFではDirect3Dでの描画ということで根本的な部分から違っています。
8
-
9
5
  [グラフィックス レンダリングの概要 - WPF .NET Framework | Microsoft Docs](https://docs.microsoft.com/ja-jp/dotnet/desktop/wpf/graphics-multimedia/wpf-graphics-rendering-overview)
10
6
 
11
-
12
-
13
7
  [図形と基本描画の概要 - WPF .NET Framework | Microsoft Docs](https://docs.microsoft.com/ja-jp/dotnet/desktop/wpf/graphics-multimedia/shapes-and-basic-drawing-in-wpf-overview)
14
-
15
-
16
8
 
17
9
  [第9回 WPFの「グラフィックス」を学ぼう:連載:WPF入門(1/2 ページ) - @IT](https://www.atmarkit.co.jp/ait/articles/1102/02/news100.html)
18
10
 
19
11
 
20
-
21
-
22
-
23
12
  > 非MVVMでの図形描画ならGridの子要素にAddする形で図形をWPFに
24
-
25
13
  > 表示できることは確認済です。
26
14
 
27
-
28
-
29
15
  これは何をAddしたのでしょうか?
30
-
31
16
  非MVVMでやったことのほうを提示していただいて、「それをMVVMで実現するアプローチ」を質問されたほうが回答しやすいかもしれません(あまりに複雑だと読む気がせず、回答がつかない可能性はあります^^;
32
17
 
33
-
34
-
35
18
  > imageコントロールに図形描画をすること自体、考え違いを
36
-
37
19
  > しているのでしょうか?
38
20
 
39
-
40
-
41
21
  [WriteableBitmap クラス (System.Windows.Media.Imaging) | Microsoft Docs](https://docs.microsoft.com/ja-jp/dotnet/api/system.windows.media.imaging.writeablebitmap)
42
-
43
22
  とかもあるにはありますが、カジュアルには描けません。
44
23
 
45
-
46
-
47
24
  画面に描画でなく画像ファイルを出力したいときに、Windows Forms的にサクッと描きたいなら↓こういったライブラリはあります。
48
-
49
25
  [NuGet Gallery | WriteableBitmapEx 1.6.7](https://www.nuget.org/packages/WriteableBitmapEx/1.6.7)
50
-
51
26
  [reneschulte/WriteableBitmapEx: Collection of extension methods for the XAML WriteableBitmap](https://github.com/reneschulte/WriteableBitmapEx)
52
-
53
-
54
27
 
55
28
  ---
56
29
 
57
-
58
-
59
30
  MVVMに強いこだわりがあるようですが、あくまで手法のひとつであり必ず使わなければならないわけではありません。
60
-
61
31
  小規模のアプリではメリットもあまりありません。
62
-
63
-
64
32
 
65
33
  もちろんWPFを使う上でMVVMは大きな武器ですので、最終的にはそうあるべきだろうとは思います。
66
34
 
67
-
68
-
69
35
  「勉強のために知りたい」・「具体例を見てみたい」とかならコードを出すこと自体は全然かまわない(回答の動機が「コードを書きたい」なので)のですが、どうしてもコード量が増えますし、内容も少し高度になってしまいます。
70
-
71
-
72
36
 
73
37
  そういったちょっと気合を入れた回答は、(質問者がドン引きするのか)なぜか反応が芳しくないのです^^;
74
38
 
75
-
76
-
77
39
  [C# - 【WPF】Dictonaryの値をコンボボックスに表示できない、クラスを参照したい|teratail](https://teratail.com/questions/345835#reply-475188)
78
-
79
-
80
40
 
81
41
  ---
82
42
 
83
-
84
-
85
43
  MVVMにするアプローチの一例です(↑の回答の使いまわし^^;
86
-
87
44
  MVVM的には非常に正しいと思うのですが、実際作りこむなら`Shape`や`Path`のコレクションを持つほうが楽だと思います(提示しておいてなんですが^^;
88
-
89
45
  [Shape クラス (System.Windows.Shapes) | Microsoft Docs](https://docs.microsoft.com/ja-jp/dotnet/api/system.windows.shapes.shape)
90
-
91
46
  [Path クラス (System.Windows.Shapes) | Microsoft Docs](https://docs.microsoft.com/ja-jp/dotnet/api/system.windows.shapes.path)
92
47
 
93
-
94
-
95
48
  動かすのがちょっと面倒だったので、雑に`MouseDragElementBehavior`を使いました(`DataTemplate`に`Grid`が入っているように、巧妙なごまかしがあります^^;
96
-
97
49
  [NuGet Gallery | Microsoft.Xaml.Behaviors.Wpf 1.1.31](https://www.nuget.org/packages/Microsoft.Xaml.Behaviors.Wpf/1.1.31)
98
50
 
99
-
100
-
101
- ```xaml
51
+ ```xml
102
-
103
52
  <Window
104
-
105
53
  x:Class="Questions349407.MainWindow"
106
-
107
54
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
108
-
109
55
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
110
-
111
56
  xmlns:behaviors="http://schemas.microsoft.com/xaml/behaviors"
112
-
113
57
  xmlns:local="clr-namespace:Questions349407"
114
-
115
58
  Width="700"
116
-
117
59
  Height="500">
118
-
119
60
  <Window.DataContext>
120
-
121
61
  <local:ViewModel />
122
-
123
62
  </Window.DataContext>
124
-
125
63
  <DockPanel>
126
-
127
64
  <Menu DockPanel.Dock="Top">
128
-
129
65
  <MenuItem Header="ずけい">
130
-
131
66
  <MenuItem Command="{Binding AddDiamondCommand}" Header="ひしがた" />
132
-
133
67
  <MenuItem Command="{Binding AddCircleCommand}" Header="まる" />
134
-
135
68
  <Separator />
136
-
137
69
  <MenuItem Command="{Binding ClearCommand}" Header="クリア" />
138
-
139
70
  </MenuItem>
140
-
141
71
  </Menu>
142
72
 
143
-
144
-
145
73
  <ItemsControl ItemsSource="{Binding Shapes}">
146
-
147
74
  <ItemsControl.Resources>
148
-
149
75
  <DataTemplate DataType="{x:Type local:Diamond}">
150
-
151
76
  <Grid>
152
-
153
77
  <Path
154
-
155
78
  Data="M100,80L150,130L100,180L50,130Z"
156
-
157
79
  Fill="RoyalBlue"
158
-
159
80
  Stretch="Fill"
160
-
161
81
  Stroke="Black"
162
-
163
82
  StrokeThickness="1">
164
-
165
83
  <behaviors:Interaction.Behaviors>
166
-
167
84
  <behaviors:MouseDragElementBehavior />
168
-
169
85
  </behaviors:Interaction.Behaviors>
170
-
171
86
  </Path>
172
-
173
87
  </Grid>
174
-
175
88
  </DataTemplate>
176
-
177
89
  <DataTemplate DataType="{x:Type local:Circle}">
178
-
179
90
  <Grid>
180
-
181
91
  <Ellipse
182
-
183
92
  Width="100"
184
-
185
93
  Height="100"
186
-
187
94
  Fill="HotPink"
188
-
189
95
  Stretch="Fill"
190
-
191
96
  Stroke="Black"
192
-
193
97
  StrokeThickness="1">
194
-
195
98
  <behaviors:Interaction.Behaviors>
196
-
197
99
  <behaviors:MouseDragElementBehavior />
198
-
199
100
  </behaviors:Interaction.Behaviors>
200
-
201
101
  </Ellipse>
202
-
203
102
  </Grid>
204
-
205
103
  </DataTemplate>
206
-
207
104
  </ItemsControl.Resources>
208
-
209
105
  <ItemsControl.ItemsPanel>
210
-
211
106
  <ItemsPanelTemplate>
212
-
213
107
  <Canvas />
214
-
215
108
  </ItemsPanelTemplate>
216
-
217
109
  </ItemsControl.ItemsPanel>
218
-
219
110
  </ItemsControl>
220
-
221
111
  </DockPanel>
222
-
223
112
  </Window>
224
-
225
113
  ```
226
114
 
227
-
228
-
229
- ```C#
115
+ ```cs
230
-
231
116
  using Reactive.Bindings;
232
-
233
117
  using System.Collections.ObjectModel;
234
-
235
118
  using System.Windows;
236
119
 
237
-
238
-
239
120
  namespace Questions349407
240
-
241
121
  {
242
-
243
122
  public interface Shape { } // System.Windows.Shapes.Shape とは無関係
244
-
245
123
  public class Diamond : Shape { }
246
-
247
124
  public class Circle : Shape { }
248
-
249
125
  public class ViewModel
250
-
251
126
  {
252
-
253
127
  public ObservableCollection<Shape> Shapes { get; } = new ObservableCollection<Shape>();
254
-
255
128
  public ReactiveCommand AddDiamondCommand { get; } = new ReactiveCommand();
256
-
257
129
  public ReactiveCommand AddCircleCommand { get; } = new ReactiveCommand();
258
-
259
130
  public ReactiveCommand ClearCommand { get; } = new ReactiveCommand();
260
131
 
261
-
262
-
263
132
  public ViewModel()
264
-
265
133
  {
266
-
267
134
  AddDiamondCommand.Subscribe(() => Shapes.Add(new Diamond()));
268
-
269
135
  AddCircleCommand.Subscribe(() => Shapes.Add(new Circle()));
270
-
271
136
  ClearCommand.Subscribe(() => Shapes.Clear());
272
-
273
137
  }
274
-
275
138
  }
276
139
 
277
-
278
-
279
140
  public partial class MainWindow : Window
280
-
281
141
  {
282
-
283
142
  public MainWindow() => InitializeComponent();
284
-
285
143
  }
286
-
287
144
  }
288
-
289
145
  ```
290
-
291
146
  ![アプリ画像](d51b340e77fb2881662a918b136c5482.png)

1

例追記

2021/07/14 11:53

投稿

TN8001
TN8001

スコア9350

test CHANGED
@@ -75,3 +75,217 @@
75
75
 
76
76
 
77
77
  [C# - 【WPF】Dictonaryの値をコンボボックスに表示できない、クラスを参照したい|teratail](https://teratail.com/questions/345835#reply-475188)
78
+
79
+
80
+
81
+ ---
82
+
83
+
84
+
85
+ MVVMにするアプローチの一例です(↑の回答の使いまわし^^;
86
+
87
+ MVVM的には非常に正しいと思うのですが、実際作りこむなら`Shape`や`Path`のコレクションを持つほうが楽だと思います(提示しておいてなんですが^^;
88
+
89
+ [Shape クラス (System.Windows.Shapes) | Microsoft Docs](https://docs.microsoft.com/ja-jp/dotnet/api/system.windows.shapes.shape)
90
+
91
+ [Path クラス (System.Windows.Shapes) | Microsoft Docs](https://docs.microsoft.com/ja-jp/dotnet/api/system.windows.shapes.path)
92
+
93
+
94
+
95
+ 動かすのがちょっと面倒だったので、雑に`MouseDragElementBehavior`を使いました(`DataTemplate`に`Grid`が入っているように、巧妙なごまかしがあります^^;
96
+
97
+ [NuGet Gallery | Microsoft.Xaml.Behaviors.Wpf 1.1.31](https://www.nuget.org/packages/Microsoft.Xaml.Behaviors.Wpf/1.1.31)
98
+
99
+
100
+
101
+ ```xaml
102
+
103
+ <Window
104
+
105
+ x:Class="Questions349407.MainWindow"
106
+
107
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
108
+
109
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
110
+
111
+ xmlns:behaviors="http://schemas.microsoft.com/xaml/behaviors"
112
+
113
+ xmlns:local="clr-namespace:Questions349407"
114
+
115
+ Width="700"
116
+
117
+ Height="500">
118
+
119
+ <Window.DataContext>
120
+
121
+ <local:ViewModel />
122
+
123
+ </Window.DataContext>
124
+
125
+ <DockPanel>
126
+
127
+ <Menu DockPanel.Dock="Top">
128
+
129
+ <MenuItem Header="ずけい">
130
+
131
+ <MenuItem Command="{Binding AddDiamondCommand}" Header="ひしがた" />
132
+
133
+ <MenuItem Command="{Binding AddCircleCommand}" Header="まる" />
134
+
135
+ <Separator />
136
+
137
+ <MenuItem Command="{Binding ClearCommand}" Header="クリア" />
138
+
139
+ </MenuItem>
140
+
141
+ </Menu>
142
+
143
+
144
+
145
+ <ItemsControl ItemsSource="{Binding Shapes}">
146
+
147
+ <ItemsControl.Resources>
148
+
149
+ <DataTemplate DataType="{x:Type local:Diamond}">
150
+
151
+ <Grid>
152
+
153
+ <Path
154
+
155
+ Data="M100,80L150,130L100,180L50,130Z"
156
+
157
+ Fill="RoyalBlue"
158
+
159
+ Stretch="Fill"
160
+
161
+ Stroke="Black"
162
+
163
+ StrokeThickness="1">
164
+
165
+ <behaviors:Interaction.Behaviors>
166
+
167
+ <behaviors:MouseDragElementBehavior />
168
+
169
+ </behaviors:Interaction.Behaviors>
170
+
171
+ </Path>
172
+
173
+ </Grid>
174
+
175
+ </DataTemplate>
176
+
177
+ <DataTemplate DataType="{x:Type local:Circle}">
178
+
179
+ <Grid>
180
+
181
+ <Ellipse
182
+
183
+ Width="100"
184
+
185
+ Height="100"
186
+
187
+ Fill="HotPink"
188
+
189
+ Stretch="Fill"
190
+
191
+ Stroke="Black"
192
+
193
+ StrokeThickness="1">
194
+
195
+ <behaviors:Interaction.Behaviors>
196
+
197
+ <behaviors:MouseDragElementBehavior />
198
+
199
+ </behaviors:Interaction.Behaviors>
200
+
201
+ </Ellipse>
202
+
203
+ </Grid>
204
+
205
+ </DataTemplate>
206
+
207
+ </ItemsControl.Resources>
208
+
209
+ <ItemsControl.ItemsPanel>
210
+
211
+ <ItemsPanelTemplate>
212
+
213
+ <Canvas />
214
+
215
+ </ItemsPanelTemplate>
216
+
217
+ </ItemsControl.ItemsPanel>
218
+
219
+ </ItemsControl>
220
+
221
+ </DockPanel>
222
+
223
+ </Window>
224
+
225
+ ```
226
+
227
+
228
+
229
+ ```C#
230
+
231
+ using Reactive.Bindings;
232
+
233
+ using System.Collections.ObjectModel;
234
+
235
+ using System.Windows;
236
+
237
+
238
+
239
+ namespace Questions349407
240
+
241
+ {
242
+
243
+ public interface Shape { } // System.Windows.Shapes.Shape とは無関係
244
+
245
+ public class Diamond : Shape { }
246
+
247
+ public class Circle : Shape { }
248
+
249
+ public class ViewModel
250
+
251
+ {
252
+
253
+ public ObservableCollection<Shape> Shapes { get; } = new ObservableCollection<Shape>();
254
+
255
+ public ReactiveCommand AddDiamondCommand { get; } = new ReactiveCommand();
256
+
257
+ public ReactiveCommand AddCircleCommand { get; } = new ReactiveCommand();
258
+
259
+ public ReactiveCommand ClearCommand { get; } = new ReactiveCommand();
260
+
261
+
262
+
263
+ public ViewModel()
264
+
265
+ {
266
+
267
+ AddDiamondCommand.Subscribe(() => Shapes.Add(new Diamond()));
268
+
269
+ AddCircleCommand.Subscribe(() => Shapes.Add(new Circle()));
270
+
271
+ ClearCommand.Subscribe(() => Shapes.Clear());
272
+
273
+ }
274
+
275
+ }
276
+
277
+
278
+
279
+ public partial class MainWindow : Window
280
+
281
+ {
282
+
283
+ public MainWindow() => InitializeComponent();
284
+
285
+ }
286
+
287
+ }
288
+
289
+ ```
290
+
291
+ ![アプリ画像](d51b340e77fb2881662a918b136c5482.png)