回答編集履歴

1

見直しキャンペーン中

2023/07/27 16:12

投稿

TN8001
TN8001

スコア9807

test CHANGED
@@ -1,443 +1,215 @@
1
1
  tarokoさんのここ1月弱の質問は、すべて関連しているんですよね?
2
-
3
2
  `Rectangle`の移動リサイズまで考えると、だいぶ先が長そうですね^^;
4
3
 
5
-
6
-
7
4
  > ・他から参照できるよう、NowData.csクラスに値を入れたい
8
5
 
9
-
10
-
11
6
  データのもと(csv等から読む予定?)をどうやって表示するかを、MVVM的にやった場合の例です。
12
7
 
13
-
14
-
15
8
  > ・全部のxamlから参照できるDictionaryは作成できるのか
16
9
 
17
-
18
-
19
10
  追加順を保持したいとのことなので、`OrderedDictionary`にしました(非ジェネリックなのでほんとにイヤなのですが^^;
20
-
21
11
  [OrderedDictionary クラス (System.Collections.Specialized) | Microsoft Docs](https://docs.microsoft.com/ja-jp/dotnet/api/system.collections.specialized.ordereddictionary)
22
12
 
23
-
24
-
25
13
  回答コードは3つのウィンドウがあります。
26
-
27
14
  * メインウィンドウ
28
-
29
15
  `DataGrid`と`Canvas`。編集・追加と可視化(マウスでは動きませんよ?^^;
30
-
31
16
  * `DetailView`ウィンドウ
32
-
33
17
  1件の詳細画面。編集も同期する。
34
-
35
18
  * `DefaultSetting`ウィンドウ
36
-
37
19
  追加時デフォルト色の設定。`Properties.Settings`を直接読み書きする。
38
20
 
39
-
40
-
41
21
  基本的には親玉(`MainWindow`)がデータ(`ViewModel`)を保持し、欲しい人(`DetailView`)に参照を渡します。
42
-
43
- 場合によっては`DefaultSetting`のように、`static`で(`Properties.Settings`)アクセスしてもいいでしょう。
22
+ 場合によっては`DefaultSetting`のように、staticで(`Properties.Settings`)アクセスしてもいいでしょう。
44
-
45
-
46
-
23
+
47
- `INotifyPropertyChanged`を実装しているクラス(`Rectan`と`Properties.Settings`)のプロパティは、変更が即Viewに反映されています(この気持ちのよさのため、長いプロパティを書いたのです^^;
24
+ `INotifyPropertyChanged`を実装しているクラス(`Rectan`と`Properties.Settings`)のプロパティは、変更が即Viewに反映されています(この気持ちのよさのため、長いプロパティを書いたのです^^
48
-
49
-
50
-
51
25
 
52
26
 
53
27
  すごい見にくくて申し訳ありませんが、1万字に圧縮するためです。
54
-
55
- App.xaml
28
+ ```xml:App.xaml
56
-
57
- ```xaml
58
-
59
29
  <Application x:Class="Questions345835.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" ShutdownMode="OnMainWindowClose" StartupUri="MainWindow.xaml">
60
-
61
30
  <Application.Resources>
62
-
63
31
  <DataTemplate x:Key="template">
64
-
65
32
  <DockPanel>
66
-
67
33
  <Ellipse Width="16" Height="16" Fill="{Binding Value}" />
68
-
69
34
  <TextBlock Margin="5,0" VerticalAlignment="Center" Text="{Binding Key}" />
70
-
71
35
  </DockPanel>
72
-
73
36
  </DataTemplate>
74
-
75
37
  </Application.Resources>
76
-
77
38
  </Application>
78
-
79
- ```
39
+ ```
80
-
81
-
82
-
83
- MainWindow.xaml
40
+ ```xml:MainWindow.xaml
84
-
85
- ```xaml
86
-
87
41
  <Window x:Class="Questions345835.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:l="clr-namespace:Questions345835" Width="800" Height="600" Left="200" Top="200">
88
-
89
42
  <Grid>
90
-
91
43
  <Grid.ColumnDefinitions>
92
-
93
44
  <ColumnDefinition />
94
-
95
45
  <ColumnDefinition />
96
-
97
46
  </Grid.ColumnDefinitions>
98
-
99
47
  <ItemsControl ItemsSource="{Binding Rectans}">
100
-
101
48
  <ItemsControl.ItemsPanel>
102
-
103
49
  <ItemsPanelTemplate>
104
-
105
50
  <Canvas Background="WhiteSmoke" />
106
-
107
51
  </ItemsPanelTemplate>
108
-
109
52
  </ItemsControl.ItemsPanel>
110
-
111
53
  <ItemsControl.ItemContainerStyle>
112
-
113
54
  <Style>
114
-
115
55
  <Setter Property="Canvas.Top" Value="{Binding Top}" />
116
-
117
56
  <Setter Property="Canvas.Left" Value="{Binding Left}" />
118
-
119
57
  </Style>
120
-
121
58
  </ItemsControl.ItemContainerStyle>
122
-
123
59
  <ItemsControl.ItemTemplate>
124
-
125
60
  <DataTemplate DataType="{x:Type l:Rectan}">
126
-
127
61
  <Rectangle Width="{Binding Width}" Height="{Binding Height}" Fill="{Binding Fill}" Stroke="{Binding Border}" StrokeThickness="5" />
128
-
129
62
  </DataTemplate>
130
-
131
63
  </ItemsControl.ItemTemplate>
132
-
133
64
  </ItemsControl>
134
-
135
65
  <DataGrid Grid.Column="1" AutoGenerateColumns="False" ItemsSource="{Binding Rectans}" SelectedItem="{Binding Current, Mode=TwoWay, TargetNullValue={x:Static CollectionView.NewItemPlaceholder}}" SelectionMode="Single">
136
-
137
66
  <DataGrid.Columns>
138
-
139
67
  <DataGridTextColumn Binding="{Binding Left}" Header="Left" />
140
-
141
68
  <DataGridTextColumn Binding="{Binding Top}" Header="Top" />
142
-
143
69
  <DataGridTextColumn Binding="{Binding Width}" Header="Width" />
144
-
145
70
  <DataGridTextColumn Binding="{Binding Height}" Header="Height" />
146
-
147
71
  <DataGridTemplateColumn Header="Border">
148
-
149
72
  <DataGridTemplateColumn.CellTemplate>
150
-
151
73
  <DataTemplate>
152
-
153
74
  <ComboBox ItemTemplate="{StaticResource template}" ItemsSource="{x:Static l:Choices.Colors}" SelectedValue="{Binding Border, UpdateSourceTrigger=PropertyChanged}" SelectedValuePath="Value" />
154
-
155
75
  </DataTemplate>
156
-
157
76
  </DataGridTemplateColumn.CellTemplate>
158
-
159
77
  </DataGridTemplateColumn>
160
-
161
78
  <DataGridTemplateColumn Header="Fill">
162
-
163
79
  <DataGridTemplateColumn.CellTemplate>
164
-
165
80
  <DataTemplate>
166
-
167
81
  <ComboBox ItemTemplate="{StaticResource template}" ItemsSource="{x:Static l:Choices.Colors}" SelectedValue="{Binding Fill, UpdateSourceTrigger=PropertyChanged}" SelectedValuePath="Value" />
168
-
169
82
  </DataTemplate>
170
-
171
83
  </DataGridTemplateColumn.CellTemplate>
172
-
173
84
  </DataGridTemplateColumn>
174
-
175
85
  </DataGrid.Columns>
176
-
177
86
  </DataGrid>
178
-
179
87
  </Grid>
180
-
181
88
  </Window>
182
-
183
- ```
89
+ ```
184
-
185
-
186
-
187
- DetailView.xaml
90
+ ```xml:DetailView.xaml
188
-
189
- ```xaml
190
-
191
91
  <Window x:Class="Questions345835.DetailView" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:l="clr-namespace:Questions345835" Title="DetailView" Width="300" Background="WhiteSmoke" Left="1000" ResizeMode="NoResize" SizeToContent="Height" Top="450">
192
-
193
92
  <StackPanel Margin="5" DataContext="{Binding Current}">
194
-
195
93
  <TextBlock Text="Left" />
196
-
197
94
  <TextBox Text="{Binding Left, UpdateSourceTrigger=PropertyChanged}" />
198
-
199
95
  <TextBlock Text="Top" />
200
-
201
96
  <TextBox Text="{Binding Top, UpdateSourceTrigger=PropertyChanged}" />
202
-
203
97
  <TextBlock Text="Width" />
204
-
205
98
  <TextBox Text="{Binding Width, UpdateSourceTrigger=PropertyChanged}" />
206
-
207
99
  <TextBlock Text="Height" />
208
-
209
100
  <TextBox Text="{Binding Height, UpdateSourceTrigger=PropertyChanged}" />
210
-
211
101
  <TextBlock Text="Border" />
212
-
213
102
  <ComboBox ItemTemplate="{StaticResource template}" ItemsSource="{x:Static l:Choices.Colors}" SelectedValue="{Binding Border, UpdateSourceTrigger=PropertyChanged}" SelectedValuePath="Value" />
214
-
215
103
  <TextBlock Text="Fill" />
216
-
217
104
  <ComboBox ItemTemplate="{StaticResource template}" ItemsSource="{x:Static l:Choices.Colors}" SelectedValue="{Binding Fill, UpdateSourceTrigger=PropertyChanged}" SelectedValuePath="Value" />
218
-
219
105
  </StackPanel>
220
-
221
106
  </Window>
222
-
223
- ```
107
+ ```
224
-
225
-
226
-
227
- DefaultSetting.xaml
108
+ ```xml:DefaultSetting.xaml
228
-
229
- ```xaml
230
-
231
109
  <Window x:Class="Questions345835.DefaultSetting" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:l="clr-namespace:Questions345835" xmlns:p="clr-namespace:Questions345835.Properties" Title="DefaultSetting" Width="300" Background="WhiteSmoke" Left="1000" ResizeMode="NoResize" SizeToContent="Height" Top="200">
232
-
233
110
  <StackPanel Margin="5">
234
-
235
111
  <Border Height="40" Margin="50,10" Background="{Binding SelectedItem.Value, ElementName=fill}" BorderBrush="{Binding SelectedItem.Value, ElementName=border}" BorderThickness="5" />
236
-
237
112
  <TextBlock Text="Border" />
238
-
239
113
  <ComboBox Name="border" ItemTemplate="{StaticResource template}" ItemsSource="{x:Static l:Choices.Colors}" SelectedValue="{Binding DefaultBorderColor, Source={x:Static p:Settings.Default}}" SelectedValuePath="Key" />
240
-
241
114
  <TextBlock Text="Fill" />
242
-
243
115
  <ComboBox Name="fill" ItemTemplate="{StaticResource template}" ItemsSource="{x:Static l:Choices.Colors}" SelectedValue="{Binding DefaultFillColor, Source={x:Static p:Settings.Default}}" SelectedValuePath="Key" />
244
-
245
116
  </StackPanel>
246
-
247
117
  </Window>
248
-
249
- ```
118
+ ```
250
-
251
-
252
-
119
+
253
- ```C#
120
+ ```cs
254
-
255
121
  using CommunityToolkit.Mvvm.ComponentModel;
256
-
257
122
  using System.Collections.ObjectModel;
258
-
259
123
  using System.Collections.Specialized;
260
-
261
124
  using System.ComponentModel;
262
-
263
125
  using System.Windows;
264
-
265
126
  using System.Windows.Media;
266
127
 
267
-
268
-
269
128
  namespace Questions345835
270
-
271
129
  {
272
-
273
130
  // コンボボックスの選択肢クラス
274
-
275
131
  public static class Choices
276
-
277
- {
132
+ {
278
-
279
133
  // ValueTupleはフィールドなのでバインドできず、Tupleは共変?じゃない
280
-
281
134
  // OrderedDictionaryは非ジェネリックで悩ましい
282
-
283
135
  public static OrderedDictionary Colors { get; } =
284
-
285
136
  new OrderedDictionary
286
-
287
137
  {
288
-
289
138
  { "赤", Brushes.Red },
290
-
291
139
  { "青", Brushes.Blue },
292
-
293
140
  { "緑", Brushes.Green },
294
-
295
141
  { "白", Brushes.White },
296
-
297
142
  { "黒", Brushes.Black },
298
-
299
143
  { "透明", Brushes.Transparent },
300
-
301
144
  };
302
-
303
- }
145
+ }
304
-
305
-
306
146
 
307
147
  // Rectangleの元データになるクラス 値の変更があるのでINotifyPropertyChangedを実装
308
-
309
148
  public class Rectan : ObservableObject
310
-
311
- {
149
+ {
312
-
313
150
  // なんだか長いですが変更通知のため仕方がありません。定型コードと割り切ってください^^;
314
-
315
151
  public double Left { get => _Left; set => SetProperty(ref _Left, value); }
316
-
317
152
  private double _Left;
318
-
319
153
  public double Top { get => _Top; set => SetProperty(ref _Top, value); }
320
-
321
154
  private double _Top;
322
-
323
155
  public double Width { get => _Width; set => SetProperty(ref _Width, value); }
324
-
325
156
  private double _Width;
326
-
327
157
  public double Height { get => _Height; set => SetProperty(ref _Height, value); }
328
-
329
158
  private double _Height;
330
-
331
159
  public Brush Border { get => _Border; set => SetProperty(ref _Border, value); }
332
-
333
160
  private Brush _Border;
334
-
335
161
  public Brush Fill { get => _Fill; set => SetProperty(ref _Fill, value); }
336
-
337
162
  private Brush _Fill;
338
163
 
339
-
340
-
341
164
  public Rectan() // 引数なしコンストラクタがないとDataGridで追加ができない
342
-
343
165
  {
344
-
345
166
  // とりあえず初期表示される値
346
-
347
167
  (Left, Top, Width, Height) = (100, 100, 100, 100);
348
-
349
168
  // デフォルトで入れたいデータ(Settings.settings)は直読み
350
-
351
169
  Border = (Brush)Choices.Colors[Properties.Settings.Default.DefaultBorderColor];
352
-
353
170
  Fill = (Brush)Choices.Colors[Properties.Settings.Default.DefaultFillColor];
354
-
355
171
  }
356
-
357
- }
172
+ }
358
-
359
-
360
173
 
361
174
  public class ViewModel : ObservableObject
362
-
363
- {
175
+ {
364
-
365
176
  // 全データ
366
-
367
177
  public ObservableCollection<Rectan> Rectans { get; } = new ObservableCollection<Rectan>();
368
178
 
369
-
370
-
371
179
  // 今参照しているデータ(全データの中の1行分のデータ)
372
-
373
180
  public Rectan Current { get => _Current; set => SetProperty(ref _Current, value); }
374
-
375
181
  private Rectan _Current;
376
182
 
377
-
378
-
379
183
  public ViewModel()
380
-
381
184
  {
382
-
383
185
  // ファイルから読んでRectansに追加する等。とりあえず1件あったことにする
384
-
385
186
  Rectans.Add(new Rectan());
386
-
387
187
  }
388
-
389
- }
188
+ }
390
-
391
-
392
189
 
393
190
  public partial class MainWindow : Window
394
-
395
- {
191
+ {
396
-
397
192
  // 場合によってはpublic staticで見せてもまあいいでしょう^^;
398
-
399
193
  //public static ViewModel VM { get; }
400
194
 
401
-
402
-
403
195
  public MainWindow()
404
-
405
196
  {
406
-
407
197
  InitializeComponent();
408
-
409
198
  var vm = new ViewModel(); // すべてのデータのもと newは1回だけ
410
-
411
199
  DataContext = vm;
412
200
 
413
-
414
-
415
201
  new DefaultSetting().Show();
416
-
417
202
  new DetailView { DataContext = vm, }.Show(); // ほしい人がいたら渡す
418
-
419
203
  }
420
204
 
421
-
422
-
423
205
  protected override void OnClosing(CancelEventArgs e) => Properties.Settings.Default.Save();
424
-
425
- }
206
+ }
426
-
427
207
  }
428
-
429
- ```
208
+ ```
430
-
431
209
  ![Settings.settings](697b89d32ba951cec831fba3116518dd.png)
432
210
 
433
-
434
-
435
211
  ![アプリ画像](868366b616f38dc1be90f48c3b22206c.png)
436
212
 
437
-
438
-
439
213
  ---
440
214
 
441
-
442
-
443
215
  実は`MouseDragElementBehavior`も試していたのですが、動的追加は未考慮(動かないわけではないがいろいろおかしい)のようでした。。。