回答編集履歴

2

見直しキャンペーン中

2023/07/26 16:10

投稿

TN8001
TN8001

スコア9862

test CHANGED
@@ -1,465 +1,233 @@
1
1
  はっきり言って丸投げ感が半端ないですが、どんどんおかしな方向に行っているので回答します(前回回答分ぐらいは反映して頂きたかったのですが。。)
2
2
 
3
-
4
-
5
3
  前回の質問では何をしようとしているのかが見えなかったのでスルーしましたが、`DependencyProperty`などは全く必要ありません。
6
-
7
4
  これに関してはPrismが悪いと思っているので、K.KATSU2さんのせいではありません。
8
5
 
9
-
10
-
11
6
  ちょっと日本語でうまく説明できないのでコードを見てください。
12
7
 
13
-
14
-
15
8
  MainWindow
16
-
17
- ```xaml
9
+ ```xml
18
-
19
10
  <Window
20
-
21
11
  x:Class="Questions334328.Views.MainWindow"
22
-
23
12
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
24
-
25
13
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
26
-
27
14
  xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
28
-
29
15
  xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
30
-
31
16
  xmlns:prism="http://prismlibrary.com/"
32
-
33
17
  xmlns:viewmodels="clr-namespace:Questions334328.ViewModels"
34
-
35
18
  xmlns:views="clr-namespace:Questions334328.Views"
36
-
37
19
  Width="500"
38
-
39
20
  Height="360"
40
-
41
21
  d:DataContext="{d:DesignInstance Type=viewmodels:MainWindowViewModel}"
42
-
43
22
  prism:ViewModelLocator.AutoWireViewModel="True"
44
-
45
23
  mc:Ignorable="d">
46
24
 
47
-
48
-
49
25
  <Window.Resources>
50
-
51
26
  <Style TargetType="Button">
52
-
53
27
  <Setter Property="Margin" Value="10" />
54
-
55
28
  <Style.Triggers>
56
-
57
29
  <Trigger Property="Command" Value="{x:Null}">
58
-
59
30
  <Setter Property="IsEnabled" Value="False" />
60
-
61
31
  </Trigger>
62
-
63
32
  </Style.Triggers>
64
-
65
33
  </Style>
66
-
67
34
  <DataTemplate DataType="{x:Type viewmodels:ActionPanelViewModel}">
68
-
69
35
  <views:ActionPanel />
70
-
71
36
  </DataTemplate>
72
-
73
37
  </Window.Resources>
74
38
 
75
-
76
-
77
39
  <DockPanel>
78
-
79
40
  <StackPanel MinWidth="100" DockPanel.Dock="Right">
80
-
81
41
  <Button Command="{Binding AddCommand}" Content="追加" />
82
-
83
42
  <Button
84
-
85
43
  Command="{Binding DelCommand}"
86
-
87
44
  CommandParameter="{Binding Items/}"
88
-
89
45
  Content="削除" />
90
-
91
46
  <Button Command="{Binding Items/OrCommand}" Content="Or" />
92
-
93
47
  <Button Command="{Binding Items/AndCommand}" Content="And" />
94
-
95
48
  </StackPanel>
96
49
 
97
-
98
-
99
50
  <DockPanel>
100
-
101
51
  <DockPanel DockPanel.Dock="Top">
102
-
103
52
  <Label Content="承認フロー名:" />
104
-
105
53
  <TextBox />
106
-
107
54
  </DockPanel>
108
-
109
55
  <!-- IsSynchronizedWithCurrentItem="True"がないと / が利かないので注意 -->
110
-
111
56
  <ListBox
112
-
113
57
  HorizontalContentAlignment="Stretch"
114
-
115
58
  IsSynchronizedWithCurrentItem="True"
116
-
117
59
  ItemsSource="{Binding Items}" />
118
-
119
60
  </DockPanel>
120
-
121
61
  </DockPanel>
122
-
123
62
  </Window>
124
-
125
- ```
63
+ ```
126
-
127
- ```C#
64
+ ```cs
128
-
129
65
  using System.Windows;
130
66
 
131
-
132
-
133
67
  namespace Questions334328.Views
134
-
135
- {
68
+ {
136
-
137
69
  public partial class MainWindow : Window
138
-
139
- {
70
+ {
140
-
141
71
  public MainWindow()
142
-
143
- {
72
+ {
144
-
145
73
  InitializeComponent();
146
-
147
- }
74
+ }
148
-
149
- }
75
+ }
150
-
151
- }
76
+ }
152
-
153
- ```
77
+ ```
154
-
155
- ```C#
78
+ ```cs
156
-
157
79
  using Prism.Commands;
158
-
159
80
  using Prism.Mvvm;
160
-
161
81
  using System.Collections.ObjectModel;
162
82
 
163
-
164
-
165
83
  namespace Questions334328.ViewModels
166
-
167
- {
84
+ {
168
-
169
85
  public class MainWindowViewModel : BindableBase
170
-
171
- {
86
+ {
172
-
173
87
  public ObservableCollection<ActionPanelViewModel> Items { get; } = new ObservableCollection<ActionPanelViewModel>();
174
88
 
175
-
176
-
177
89
  public DelegateCommand AddCommand { get; }
178
-
179
90
  public DelegateCommand<ActionPanelViewModel> DelCommand { get; }
180
91
 
181
-
182
-
183
92
  public MainWindowViewModel()
184
-
185
- {
93
+ {
186
-
187
94
  AddCommand = new DelegateCommand(ExecuteAddCommand);
188
-
189
95
  DelCommand = new DelegateCommand<ActionPanelViewModel>(ExecuteDelCommand, CanExecuteDelCommand)
190
-
191
96
  .ObservesProperty(() => Items.Count); // アイテムがなければ押せない どのプロパティを監視してCanExecuteDelCommandを走らせるかをラムダ式(式木)で指定
192
-
193
- }
97
+ }
194
-
195
-
196
98
 
197
99
  private void ExecuteAddCommand()
198
-
199
- {
100
+ {
200
-
201
101
  Items.Add(new ActionPanelViewModel { No = Items.Count + 1, });
202
-
203
- }
102
+ }
204
-
205
-
206
103
 
207
104
  private bool CanExecuteDelCommand(ActionPanelViewModel arg)
208
-
209
- {
105
+ {
210
-
211
106
  return 0 < Items.Count;
212
-
213
- }
107
+ }
214
-
215
108
  private void ExecuteDelCommand(ActionPanelViewModel item)
216
-
217
- {
109
+ {
218
-
219
110
  Items.Remove(item);
220
-
221
111
  for (var i = 0; i < Items.Count; i++) Items[i].No = i + 1; // No振り直し
222
-
223
- }
112
+ }
224
-
225
- }
113
+ }
226
-
227
- }
114
+ }
228
-
229
- ```
115
+ ```
230
-
231
-
232
116
 
233
117
  ActionPanel
234
-
235
- ```xaml
118
+ ```xml
236
-
237
119
  <UserControl
238
-
239
120
  x:Class="Questions334328.Views.ActionPanel"
240
-
241
121
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
242
-
243
122
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
244
-
245
123
  xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
246
-
247
124
  xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
248
-
249
125
  xmlns:viewmodels="clr-namespace:Questions334328.ViewModels"
250
-
251
126
  d:DataContext="{d:DesignInstance Type=viewmodels:ActionPanelViewModel}"
252
-
253
127
  d:DesignHeight="60"
254
-
255
128
  d:DesignWidth="340"
256
-
257
129
  mc:Ignorable="d">
258
-
259
130
  <StackPanel>
260
-
261
131
  <Grid>
262
-
263
132
  <Grid.ColumnDefinitions>
264
-
265
133
  <ColumnDefinition Width="Auto" MinWidth="20" />
266
-
267
134
  <ColumnDefinition Width="173*" />
268
-
269
135
  <ColumnDefinition Width="130*" />
270
-
271
136
  </Grid.ColumnDefinitions>
272
-
273
137
  <TextBlock FontSize="14" Text="{Binding No}" />
274
-
275
138
  <ComboBox
276
-
277
139
  Grid.Column="1"
278
-
279
140
  Margin="10,0"
280
-
281
141
  DisplayMemberPath="DisplayValue"
282
-
283
142
  ItemsSource="{Binding People}"
284
-
285
143
  SelectedItem="{Binding SelectedAuthority, Mode=TwoWay}"
286
-
287
144
  SelectedValue="Value" />
288
-
289
145
  <ComboBox
290
-
291
146
  Grid.Column="2"
292
-
293
147
  Margin="10,0"
294
-
295
148
  DisplayMemberPath="DisplayValue"
296
-
297
149
  ItemsSource="{Binding Authority}"
298
-
299
150
  SelectedItem="{Binding SelectedAuthority, Mode=TwoWay}"
300
-
301
151
  SelectedValue="Value" />
302
-
303
152
  </Grid>
304
153
 
305
-
306
-
307
154
  <Label
308
-
309
155
  Content="{Binding Indicator}"
310
-
311
156
  FontFamily="Yu Gothic UI Semibold"
312
-
313
157
  FontSize="14"
314
-
315
158
  FontWeight="Bold" />
316
-
317
159
  </StackPanel>
318
-
319
160
  </UserControl>
320
-
321
- ```
161
+ ```
322
-
323
- ```C#
162
+ ```cs
324
-
325
163
  using System.Windows.Controls;
326
164
 
327
-
328
-
329
165
  namespace Questions334328.Views
330
-
331
- {
166
+ {
332
-
333
167
  public partial class ActionPanel : UserControl
334
-
335
- {
168
+ {
336
-
337
169
  public ActionPanel()
338
-
339
- {
170
+ {
340
-
341
171
  InitializeComponent();
342
-
343
- }
172
+ }
344
-
345
- }
173
+ }
346
-
347
- }
174
+ }
348
-
349
- ```
175
+ ```
350
-
351
- ```C#
176
+ ```cs
352
-
353
177
  using Prism.Commands;
354
-
355
178
  using Prism.Mvvm;
356
-
357
179
  using System;
358
180
 
359
-
360
-
361
181
  namespace Questions334328.ViewModels
362
-
363
- {
182
+ {
364
-
365
183
  public class ActionPanelViewModel : BindableBase
366
-
367
- {
184
+ {
368
-
369
185
  private int _No;
370
-
371
186
  public int No { get => _No; set => SetProperty(ref _No, value); }
372
187
 
373
-
374
-
375
188
  private string _Indicator = "↓";
376
-
377
189
  public string Indicator { get => _Indicator; set => SetProperty(ref _Indicator, value); }
378
190
 
379
-
380
-
381
191
  public DelegateCommand OrCommand { get; }
382
-
383
192
  public DelegateCommand AndCommand { get; }
384
193
 
385
-
386
-
387
194
  public ActionPanelViewModel()
388
-
389
- {
195
+ {
390
-
391
196
  OrCommand = new DelegateCommand(ExecuteOrCommand/*() => Indicator = "Or"*/);
392
-
393
197
  AndCommand = new DelegateCommand(ExecuteAndCommand/*() => Indicator = "And"*/);
394
-
395
- }
198
+ }
396
-
397
-
398
199
 
399
200
  private void ExecuteOrCommand()
400
-
401
- {
201
+ {
402
-
403
202
  Indicator = "Or";
404
-
405
- }
203
+ }
406
-
407
204
  private void ExecuteAndCommand()
408
-
409
- {
205
+ {
410
-
411
206
  Indicator = "And";
412
-
413
- }
207
+ }
414
-
415
- }
208
+ }
416
-
417
- }
209
+ }
418
-
419
- ```
210
+ ```
420
-
421
-
422
211
 
423
212
  質問コードでは`Item`が`DataTemplate`で`ActionPanel`になり、`DataContext`に`ActionPanelViewModel`がインジェクションされるという流れです。
424
-
425
213
  ロジック上は不要な`Item`があったり、`ViewModel`がインジェクションされるため「どういじればいいんだ?」となります。
426
214
 
427
-
428
-
429
215
  回答コードは`ActionPanelViewModel`が`DataTemplate`で`ActionPanel`になり、`DataContext`は`ActionPanelViewModel`をそのまま引き継ぎます。
430
-
431
216
  `ActionPanelViewModel`の増減やプロパティの変更が、そのまま`View`に反映されます。
432
217
 
433
-
434
-
435
218
  言葉以上にシンプルで非常にすっきりしていると感じられると思います^^
436
219
 
437
220
 
438
-
439
-
440
-
441
221
  `OrCommand`・`AndCommand`は`ActionPanelViewModel`側で実装しましたが、メイン側に移したければ`DelCommand`と同じようにするだけです。
442
222
 
443
-
444
-
445
223
  `{Binding Items/}`等の`/`については↓を参照してください。
446
-
447
224
  [データ バインディングの概要 - WPF .NET Framework | Microsoft Docs](https://docs.microsoft.com/ja-jp/dotnet/desktop/wpf/data/data-binding-overview?view=netframeworkdesktop-4.8#current-item-pointers)
448
225
 
449
-
450
-
451
226
  [方法: 階層データでマスター詳細パターンを使用する - WPF .NET Framework | Microsoft Docs](https://docs.microsoft.com/ja-jp/dotnet/desktop/wpf/data/how-to-use-the-master-detail-pattern-with-hierarchical-data?view=netframeworkdesktop-4.8&viewFallbackFrom=netdesktop-5.0)
452
227
 
453
-
454
-
455
228
  ---
456
229
 
457
-
458
-
459
230
  過去にも何度かPrism関連で回答しているのですが、おかしなことになっていることが非常に多いです。
460
-
461
231
  Prismは`UserControl`・`ViewModel`をセットで生成するため、こういった勘違いを誘発している気がします。
462
232
 
463
-
464
-
465
233
  WPFに精通した方が大規模開発する場合は有用なんだろうとは思いますが、私はどうも好きになれません^^;

1

できるだけメソッドに書き換え

2021/04/22 05:00

投稿

TN8001
TN8001

スコア9862

test CHANGED
@@ -138,7 +138,13 @@
138
138
 
139
139
  {
140
140
 
141
+ public MainWindow()
142
+
143
+ {
144
+
141
- public MainWindow() => InitializeComponent();
145
+ InitializeComponent();
146
+
147
+ }
142
148
 
143
149
  }
144
150
 
@@ -180,15 +186,31 @@
180
186
 
181
187
  AddCommand = new DelegateCommand(ExecuteAddCommand);
182
188
 
183
- DelCommand = new DelegateCommand<ActionPanelViewModel>(ExecuteDelCommand, _ => 0 < Items.Count)
189
+ DelCommand = new DelegateCommand<ActionPanelViewModel>(ExecuteDelCommand, CanExecuteDelCommand)
184
-
190
+
185
- .ObservesProperty(() => Items.Count); // アイテムがなければ押せない
191
+ .ObservesProperty(() => Items.Count); // アイテムがなければ押せない どのプロパティを監視してCanExecuteDelCommandを走らせるかをラムダ式(式木)で指定
186
-
192
+
187
- }
193
+ }
194
+
195
+
196
+
188
-
197
+ private void ExecuteAddCommand()
198
+
189
-
199
+ {
190
-
200
+
191
- private void ExecuteAddCommand() => Items.Add(new ActionPanelViewModel { No = Items.Count + 1, });
201
+ Items.Add(new ActionPanelViewModel { No = Items.Count + 1, });
202
+
203
+ }
204
+
205
+
206
+
207
+ private bool CanExecuteDelCommand(ActionPanelViewModel arg)
208
+
209
+ {
210
+
211
+ return 0 < Items.Count;
212
+
213
+ }
192
214
 
193
215
  private void ExecuteDelCommand(ActionPanelViewModel item)
194
216
 
@@ -196,7 +218,7 @@
196
218
 
197
219
  Items.Remove(item);
198
220
 
199
- for (var i = 0; i < Items.Count; i++) Items[i].No = i + 1; // No.振り直し
221
+ for (var i = 0; i < Items.Count; i++) Items[i].No = i + 1; // No振り直し
200
222
 
201
223
  }
202
224
 
@@ -312,7 +334,13 @@
312
334
 
313
335
  {
314
336
 
337
+ public ActionPanel()
338
+
339
+ {
340
+
315
- public ActionPanel() => InitializeComponent();
341
+ InitializeComponent();
342
+
343
+ }
316
344
 
317
345
  }
318
346
 
@@ -326,6 +354,8 @@
326
354
 
327
355
  using Prism.Mvvm;
328
356
 
357
+ using System;
358
+
329
359
 
330
360
 
331
361
  namespace Questions334328.ViewModels
@@ -358,9 +388,27 @@
358
388
 
359
389
  {
360
390
 
361
- OrCommand = new DelegateCommand(() => Indicator = "Or");
391
+ OrCommand = new DelegateCommand(ExecuteOrCommand/*() => Indicator = "Or"*/);
362
-
392
+
363
- AndCommand = new DelegateCommand(() => Indicator = "And");
393
+ AndCommand = new DelegateCommand(ExecuteAndCommand/*() => Indicator = "And"*/);
394
+
395
+ }
396
+
397
+
398
+
399
+ private void ExecuteOrCommand()
400
+
401
+ {
402
+
403
+ Indicator = "Or";
404
+
405
+ }
406
+
407
+ private void ExecuteAndCommand()
408
+
409
+ {
410
+
411
+ Indicator = "And";
364
412
 
365
413
  }
366
414