回答編集履歴

1

見直しキャンペーン中

2023/07/23 04:03

投稿

TN8001
TN8001

スコア9326

test CHANGED
@@ -1,459 +1,230 @@
1
1
  単独選択か複数選択かで変わってきます。
2
-
3
2
  見てもらったほうが早いので、それぞれ向き用の2つの表示法を用意しました。
4
-
5
3
  `SelectionMode`をコンボボックスで切り替えられるようになっています。違いを確認してください。
6
4
 
7
-
8
-
9
- ```xaml
5
+ ```xml
10
-
11
6
  <Window
12
-
13
7
  x:Class="Questions284783.Views.MainWindow"
14
-
15
8
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
16
-
17
9
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
18
-
19
10
  xmlns:controls="clr-namespace:System.Windows.Controls;assembly=PresentationFramework"
20
-
21
11
  xmlns:prism="http://prismlibrary.com/"
22
-
23
12
  xmlns:sys="clr-namespace:System;assembly=mscorlib"
24
-
25
13
  Width="525"
26
-
27
14
  Height="350"
28
-
29
15
  prism:ViewModelLocator.AutoWireViewModel="True">
30
16
 
31
-
32
-
33
17
  <!-- prism:ViewModelLocator.AutoWireViewModel="True" があるからいらないはず -->
34
-
35
18
  <!--<Window.DataContext>
36
-
37
19
  <l:MainWindowViewModel />
38
-
39
20
  </Window.DataContext>-->
40
21
 
41
-
42
-
43
22
  <Window.Resources>
44
-
45
23
  <!-- SelectionMode選択用データ(本題には無関係 違いを確認しやすいように) -->
46
-
47
24
  <ObjectDataProvider
48
-
49
25
  x:Key="selectionMode"
50
-
51
26
  MethodName="GetValues"
52
-
53
27
  ObjectType="{x:Type sys:Enum}">
54
-
55
28
  <ObjectDataProvider.MethodParameters>
56
-
57
29
  <x:Type TypeName="controls:SelectionMode" />
58
-
59
30
  </ObjectDataProvider.MethodParameters>
60
-
61
31
  </ObjectDataProvider>
62
-
63
32
  </Window.Resources>
64
33
 
65
-
66
-
67
34
  <Grid>
68
-
69
35
  <Grid.ColumnDefinitions>
70
-
71
36
  <ColumnDefinition />
72
-
73
37
  <ColumnDefinition Width="2*" />
74
-
75
38
  </Grid.ColumnDefinitions>
76
-
77
39
  <Grid.RowDefinitions>
78
-
79
40
  <RowDefinition Height="Auto" />
80
-
81
41
  <RowDefinition />
82
-
83
42
  </Grid.RowDefinitions>
84
43
 
85
-
86
-
87
44
  <Grid>
88
-
89
45
  <Grid.ColumnDefinitions>
90
-
91
46
  <ColumnDefinition Width="Auto" />
92
-
93
47
  <ColumnDefinition />
94
-
95
48
  </Grid.ColumnDefinitions>
96
-
97
49
  <Label
98
-
99
- Margin="5"
50
+ Margin="5"
100
-
101
- VerticalAlignment="Center"
51
+ VerticalAlignment="Center"
102
-
103
52
  Content="表題" />
104
-
105
53
  <TextBox
106
-
107
54
  Grid.Column="1"
108
-
109
- Margin="5"
55
+ Margin="5"
110
-
111
- VerticalAlignment="Center"
56
+ VerticalAlignment="Center"
112
-
113
57
  Text="{Binding Txt_Title, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
114
-
115
58
  TextWrapping="Wrap" />
116
-
117
- </Grid>
59
+ </Grid>
118
-
119
-
120
60
 
121
61
  <Grid Grid.Column="1">
122
-
123
62
  <Grid.ColumnDefinitions>
124
-
125
63
  <ColumnDefinition Width="Auto" />
126
-
127
64
  <ColumnDefinition />
128
-
129
65
  <ColumnDefinition Width="Auto" />
130
-
131
66
  </Grid.ColumnDefinitions>
132
-
133
67
  <Label
134
-
135
- Margin="5"
68
+ Margin="5"
136
-
137
- VerticalAlignment="Center"
69
+ VerticalAlignment="Center"
138
-
139
70
  Content="Memo" />
140
-
141
71
  <TextBox
142
-
143
72
  Grid.Column="1"
144
-
145
- Margin="5"
73
+ Margin="5"
146
-
147
- VerticalAlignment="Center"
74
+ VerticalAlignment="Center"
148
-
149
75
  Text="{Binding Txt_Memo, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
150
-
151
76
  TextWrapping="Wrap" />
152
-
153
77
  <Button
154
-
155
78
  Grid.Column="2"
156
-
157
79
  MinWidth="56"
158
-
159
- Margin="5"
80
+ Margin="5"
160
-
161
81
  Command="{Binding ExecuteCommand}"
162
-
163
82
  Content="追加" />
164
-
165
- </Grid>
83
+ </Grid>
166
-
167
-
168
84
 
169
85
  <Grid Grid.Row="1">
170
-
171
86
  <Grid.RowDefinitions>
172
-
173
87
  <RowDefinition Height="Auto" />
174
-
175
88
  <RowDefinition />
176
-
177
89
  </Grid.RowDefinitions>
178
90
 
179
-
180
-
181
91
  <!-- SelectionMode選択 -->
182
-
183
92
  <ComboBox
184
-
185
93
  x:Name="comboBox"
186
-
187
- Margin="5"
94
+ Margin="5"
188
-
189
95
  ItemsSource="{Binding Source={StaticResource selectionMode}}"
190
-
191
96
  SelectedIndex="0" />
192
-
193
97
  <ListBox
194
-
195
98
  x:Name="lst_Title"
196
-
197
99
  Grid.Row="1"
198
-
199
- Margin="5"
100
+ Margin="5"
200
-
201
101
  DisplayMemberPath="Title"
202
-
203
102
  IsSynchronizedWithCurrentItem="True"
204
-
205
103
  ItemsSource="{Binding TaskList}"
206
-
207
104
  SelectionMode="{Binding SelectedValue, ElementName=comboBox}" />
208
-
209
- </Grid>
105
+ </Grid>
210
-
211
-
212
106
 
213
107
  <Grid Grid.Row="1" Grid.Column="1">
214
-
215
108
  <Grid.RowDefinitions>
216
-
217
109
  <RowDefinition />
218
-
219
110
  <RowDefinition Height="Auto" />
220
-
221
111
  </Grid.RowDefinitions>
222
112
 
223
-
224
-
225
113
  <!-- SelectedItems をもらう -->
226
-
227
114
  <ListBox Margin="5" ItemsSource="{Binding SelectedItems, ElementName=lst_Title}">
228
-
229
115
  <ListBox.ItemTemplate>
230
-
231
116
  <DataTemplate>
232
-
233
117
  <StackPanel>
234
-
235
118
  <TextBlock FontWeight="Bold" Text="{Binding Title}" />
236
-
237
119
  <TextBlock Text="{Binding Detail}" />
238
-
239
120
  </StackPanel>
240
-
241
121
  </DataTemplate>
242
-
243
122
  </ListBox.ItemTemplate>
244
-
245
123
  </ListBox>
246
124
 
247
-
248
-
249
125
  <!-- lst_Title が SelectionMode="Single" ならこれもあり -->
250
-
251
126
  <StackPanel Grid.Row="1">
252
-
253
127
  <TextBlock
254
-
255
128
  Margin="5"
256
-
257
129
  FontWeight="Bold"
258
-
259
130
  Text="{Binding TaskList/Title}" />
260
-
261
131
  <TextBlock Margin="5" Text="{Binding TaskList/Detail}" />
262
-
263
132
  </StackPanel>
264
-
265
- </Grid>
133
+ </Grid>
266
-
267
134
  </Grid>
268
-
269
135
  </Window>
270
-
271
136
  ```
272
137
 
273
-
274
-
275
- ```C#
138
+ ```cs
276
-
277
139
  using System.Collections.ObjectModel;
278
-
279
140
  using Prism.Commands;
280
-
281
141
  using Prism.Mvvm;
282
142
 
283
-
284
-
285
143
  namespace Questions284783.ViewModels
286
-
287
144
  {
288
-
289
145
  public class MainWindowViewModel : BindableBase
290
-
291
146
  {
292
-
293
147
  private string txt_Title;
294
-
295
148
  public string Txt_Title
296
-
297
- {
149
+ {
298
-
299
150
  get => txt_Title;
300
-
301
151
  set
302
-
303
152
  {
304
-
305
153
  if(SetProperty(ref txt_Title, value))
306
-
307
154
  ExecuteCommand.RaiseCanExecuteChanged();
308
-
309
155
  }
310
-
311
- }
156
+ }
312
-
313
-
314
157
 
315
158
  private string txt_Memo;
316
-
317
159
  public string Txt_Memo
318
-
319
- {
160
+ {
320
-
321
161
  get => txt_Memo;
322
-
323
162
  set
324
-
325
163
  {
326
-
327
164
  if(SetProperty(ref txt_Memo, value))
328
-
329
165
  ExecuteCommand.RaiseCanExecuteChanged();
330
-
331
166
  }
332
-
333
- }
167
+ }
334
-
335
-
336
168
 
337
169
  public ObservableCollection<Task> TaskList { get; } = new ObservableCollection<Task>();
338
170
 
339
-
340
-
341
171
  public DelegateCommand ExecuteCommand { get; private set; }
342
172
 
343
-
344
-
345
173
  public MainWindowViewModel()
346
-
347
- {
174
+ {
348
-
349
175
  // 検証時面倒なので先入れ^^;
350
-
351
176
  TaskList.Add(new Task { Title = "aaa", Detail = "111" });
352
-
353
177
  TaskList.Add(new Task { Title = "bbb", Detail = "222" });
354
-
355
178
  TaskList.Add(new Task { Title = "ccc", Detail = "333" });
356
179
 
357
-
358
-
359
180
  ExecuteCommand = new DelegateCommand(Execute, CanExecute);
360
-
361
- }
181
+ }
362
-
363
-
364
182
 
365
183
  private void Execute()
366
-
367
- {
184
+ {
368
-
369
185
  TaskList.Add(new Task { Title = Txt_Title, Detail = Txt_Memo });
370
186
 
371
-
372
-
373
187
  Txt_Title = "";
374
-
375
188
  Txt_Memo = "";
376
189
 
377
-
378
-
379
190
  ExecuteCommand.RaiseCanExecuteChanged();
380
-
381
- }
191
+ }
382
-
383
-
384
192
 
385
193
  private bool CanExecute() => !string.IsNullOrEmpty(Txt_Title);
386
-
387
194
  }
388
195
 
389
-
390
-
391
196
  public class Task
392
-
393
197
  {
394
-
395
198
  public string Title { get; set; }
396
-
397
199
  public string Detail { get; set; }
398
-
399
200
  }
400
-
401
201
  }
402
-
403
202
  ```
404
203
 
405
204
 
406
-
407
-
408
-
409
205
  バインディング中のスラッシュ`{Binding TaskList/Title}`については↓あたりを参照してください(説明放棄^^;
410
-
411
206
  [方法: 階層データでマスター詳細パターンを使用する - WPF | Microsoft Docs](https://docs.microsoft.com/ja-jp/dotnet/framework/wpf/data/how-to-use-the-master-detail-pattern-with-hierarchical-data)
412
-
413
207
  [WPF4.5入門 その56「コレクションのバインディング」 - かずきのBlog@hatena](https://blog.okazuki.jp/entry/2014/10/29/220236) 最後のほうの「現在の選択項目をバインディングする方法」
414
208
 
415
-
416
-
417
209
  ---
418
210
 
419
-
420
-
421
211
  ここまでは`View`だけでの対応ですが、選択されているというのが重要な情報の場合(ファイルに選択情報も保存して次回復元する等)は、別の手のほうがいいかもしれません。
422
212
 
423
-
424
-
425
213
  `Task`クラスに`bool IsSelected`プロパティを用意して、`lst_Title`では`ListBoxItem`の`IsSelected`にバインドし、`lst_Detail`では`ListBoxItem`の`Visibility`にバインドします。
426
-
427
214
  どちらの`ListBox`も`TaskList`がソースですが、`lst_Detail`では未選択のものは無いように見えます。
428
-
429
215
  ちょっとずるいようですが、割とポピュラーな手段だと思います。もし気になるようでしたら追記しますので言ってください。
430
216
 
431
-
432
-
433
217
  ---
434
218
 
435
-
436
-
437
219
  > ソースコードに改善点ありましたらご指摘願います。
438
220
 
439
-
440
-
441
221
  `prism:ViewModelLocator.AutoWireViewModel="True"`があるので`<l:MainWindowViewModel />`で入れる必要はないはずです。
442
222
 
443
-
444
-
445
223
  ぐちゃぐちゃ`Margin`(`Margin="66,5,122,5"`のようなもの)はよろしくないです(`Margin="5"`や`Margin="5,2"`のようなすっきりしたものならOKです)
446
-
447
224
  ユーザーのフォント設定やウィンドウのリサイズ等で、文字が見切れたりレイアウト崩れの原因になります。
448
-
449
225
  はっきり言って面倒なのですが、入れ子`Grid`等で地道にレイアウトしてください。
450
226
 
451
-
452
-
453
227
  `Width="56"`もフォントによっては見切れるので、`MinWidth="56"`にしておくと安心です。
454
228
 
455
-
456
-
457
229
  C#コードは特にないです^^
458
-
459
230
  `ReactiveProperty`を使えば、プロパティのごちゃっとしたところを緩和できそうです。