回答編集履歴

3

見直しキャンペーン中

2023/07/27 13:35

投稿

TN8001
TN8001

スコア9326

test CHANGED
@@ -1,457 +1,229 @@
1
1
  > 1)選択が解除できず、ずっとGrayのスタイルが残る
2
2
 
3
-
4
-
5
3
  ~~`MoveCurrentToPosition(-1)`でもすればいいんじゃないですかね?~~
6
-
7
4
  ~~[CollectionView.MoveCurrentToPosition(Int32) メソッド (System.Windows.Data) | Microsoft Docs](https://docs.microsoft.com/ja-jp/dotnet/api/system.windows.data.collectionview.movecurrenttoposition)~~
8
5
 
9
-
10
-
11
6
  [ApplicationCommands.SelectAll プロパティ (System.Windows.Input) | Microsoft Docs](https://docs.microsoft.com/ja-jp/dotnet/api/system.windows.input.applicationcommands.selectall)
12
-
13
7
  との対称性を考えて`RoutedCommand`にしてみました。
14
-
15
- `View`で完結するのがいい点ですが、`ViewModel`でどうこうしたい場合は逆に扱いにくいです^^;
8
+ Viewで完結するのがいい点ですが、ViewModelでどうこうしたい場合は逆に扱いにくいです^^;
16
-
17
-
18
9
 
19
10
  > 2)TextBoxを選択、☑を操作した時に、LightGrayにならない。
20
11
 
21
-
22
-
23
12
  フォーカスが`TextBox`や`CheckBox`に行きますから当然そうなりますね。
24
-
25
13
  `SelectionUnit="Cell"`でいいならこんな感じで行けましたがどうでしょうか。
26
14
 
27
-
28
-
29
15
  参考
30
-
31
16
  [wpf - DataGrid SelectionUnit=Cell disables all support for a selected row? - Stack Overflow](https://stackoverflow.com/questions/9489041/datagrid-selectionunit-cell-disables-all-support-for-a-selected-row)
32
17
 
33
-
34
-
35
- ```xaml
18
+ ```xml
36
-
37
19
  <Window
38
-
39
20
  x:Class="Questions337191.Views.MainWindow"
40
-
41
21
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
42
-
43
22
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
44
-
45
23
  xmlns:b="http://schemas.microsoft.com/xaml/behaviors"
46
-
47
24
  xmlns:v="clr-namespace:Questions337191.Views"
48
-
49
25
  xmlns:vm="clr-namespace:Questions337191.ViewModels"
50
-
51
26
  Width="525"
52
-
53
27
  Height="350">
54
-
55
28
  <Window.DataContext>
56
-
57
29
  <vm:MainWindowViewModel />
58
-
59
30
  </Window.DataContext>
60
-
61
31
  <DockPanel>
62
-
63
32
  <!--
64
-
65
33
  メニューから呼ぶとなぜか激重になる。
66
-
67
34
  以降ボタンから呼んでもDataGridの左上ボタンでも同じく激重。
68
-
69
35
  意味が分からないw
70
-
71
36
  -->
72
-
73
37
  <!--<Menu DockPanel.Dock="Top">
74
-
75
38
  <MenuItem Header="編集">
76
-
77
39
  <MenuItem Command="ApplicationCommands.SelectAll" CommandTarget="{Binding ElementName=dataGrid}" />
78
-
79
40
  <MenuItem Command="v:DataGridBehavior.UnselectAll" CommandTarget="{Binding ElementName=dataGrid}" />
80
-
81
41
  </MenuItem>
82
-
83
42
  </Menu>-->
84
-
85
43
  <Grid>
86
-
87
44
  <Grid.RowDefinitions>
88
-
89
45
  <RowDefinition Height="Auto" />
90
-
91
46
  <RowDefinition />
92
-
93
47
  </Grid.RowDefinitions>
94
-
95
48
  <StackPanel Orientation="Horizontal">
96
-
97
49
  <Button
98
-
99
50
  MinWidth="100"
100
-
101
51
  Margin="5"
102
-
103
52
  Command="ApplicationCommands.SelectAll"
104
-
105
53
  CommandTarget="{Binding ElementName=dataGrid}"
106
-
107
54
  Content="すべて選択" />
108
-
109
55
  <Button
110
-
111
56
  MinWidth="100"
112
-
113
57
  Margin="5"
114
-
115
58
  Command="v:DataGridBehavior.UnselectAll"
116
-
117
59
  CommandTarget="{Binding ElementName=dataGrid}"
118
-
119
60
  Content="選択解除" />
120
-
121
61
  </StackPanel>
122
62
 
123
-
124
-
125
63
  <DataGrid
126
-
127
64
  x:Name="dataGrid"
128
-
129
65
  Grid.Row="1"
130
-
131
66
  ItemsSource="{Binding MyList}"
132
-
133
67
  SelectionUnit="Cell">
134
-
135
68
  <b:Interaction.Behaviors>
136
-
137
69
  <v:DataGridBehavior />
138
-
139
70
  </b:Interaction.Behaviors>
140
-
141
71
  <DataGrid.RowStyle>
142
-
143
72
  <Style TargetType="DataGridRow">
144
-
145
73
  <Setter Property="Height" Value="20" />
146
-
147
74
  <Style.Triggers>
148
-
149
75
  <Trigger Property="v:DataGridAttachedProperties.IsCellSelected" Value="True">
150
-
151
76
  <Setter Property="Height" Value="40" />
152
-
153
77
  <Setter Property="Background" Value="Gray" />
154
-
155
78
  </Trigger>
156
-
157
79
  </Style.Triggers>
158
-
159
80
  </Style>
160
-
161
81
  </DataGrid.RowStyle>
162
82
 
163
-
164
-
165
83
  <DataGrid.CellStyle>
166
-
167
84
  <Style TargetType="DataGridCell">
168
-
169
85
  <Style.Triggers>
170
-
171
86
  <Trigger Property="IsSelected" Value="True">
172
-
173
87
  <Setter Property="Background" Value="LightGray" />
174
-
175
88
  <Setter Property="v:DataGridAttachedProperties.IsCellSelected" Value="True" />
176
-
177
89
  </Trigger>
178
-
179
90
  <Trigger Property="IsSelected" Value="False">
180
-
181
91
  <Setter Property="v:DataGridAttachedProperties.IsCellSelected" Value="False" />
182
-
183
92
  </Trigger>
184
-
185
93
  </Style.Triggers>
186
-
187
94
  </Style>
188
-
189
95
  </DataGrid.CellStyle>
190
96
 
191
-
192
-
193
97
  <DataGrid.Columns>
194
-
195
98
  <DataGridTemplateColumn Width="100">
196
-
197
99
  <DataGridTemplateColumn.CellTemplate>
198
-
199
100
  <DataTemplate>
200
-
201
101
  <StackPanel Orientation="Horizontal">
202
-
203
102
  <TextBox Text="コメント" />
204
-
205
103
  <TextBlock Text="○" />
206
-
207
104
  </StackPanel>
208
-
209
105
  </DataTemplate>
210
-
211
106
  </DataGridTemplateColumn.CellTemplate>
212
-
213
107
  </DataGridTemplateColumn>
214
-
215
108
  </DataGrid.Columns>
216
-
217
109
  </DataGrid>
218
-
219
110
  </Grid>
220
-
221
111
  </DockPanel>
222
-
223
112
  </Window>
224
-
225
113
  ```
226
114
 
227
-
228
-
229
- ```C#
115
+ ```cs
230
-
231
116
  using Livet;
232
-
233
117
  using System.Collections.ObjectModel;
234
-
235
118
  using System.Linq;
236
119
 
237
-
238
-
239
120
  namespace Questions337191.ViewModels
240
-
241
121
  {
242
-
243
122
  public class MainWindowViewModel : ViewModel
244
-
245
- {
123
+ {
246
-
247
124
  public ObservableCollection<Person> MyList { get; }
248
125
 
249
-
250
-
251
126
  public MainWindowViewModel()
252
-
253
- {
127
+ {
254
-
255
128
  MyList = new ObservableCollection<Person>(
256
-
257
129
  Enumerable.Range(1, 10_000).Select(i => new Person
258
-
259
130
  {
260
-
261
131
  Name = "田中" + i,
262
-
263
132
  Age = 20 + i,
264
-
265
133
  AuthMember = i % 2 == 0,
266
-
267
134
  }));
268
-
269
- }
135
+ }
270
-
271
- }
136
+ }
272
-
273
-
274
137
 
275
138
  public class Person
276
-
277
- {
139
+ {
278
-
279
140
  public string Name { get; set; }
280
-
281
141
  public int Age { get; set; }
282
-
283
142
  public bool AuthMember { get; set; }
284
-
285
- }
143
+ }
286
-
287
144
  }
288
-
289
145
  ```
290
146
 
291
-
292
-
293
- ```C#
147
+ ```cs
294
-
295
148
  using Microsoft.Xaml.Behaviors;
296
-
297
149
  using System.Linq;
298
-
299
150
  using System.Windows;
300
-
301
151
  using System.Windows.Controls;
302
-
303
152
  using System.Windows.Input;
304
-
305
153
  using System.Windows.Media;
306
154
 
307
-
308
-
309
155
  namespace Questions337191.Views
310
-
311
156
  {
312
-
313
157
  // [wpf - DataGrid SelectionUnit=Cell disables all support for a selected row? - Stack Overflow](https://stackoverflow.com/questions/9489041/datagrid-selectionunit-cell-disables-all-support-for-a-selected-row)
314
-
315
158
  public static class DataGridAttachedProperties
316
-
317
- {
159
+ {
318
-
319
160
  public static bool GetIsCellSelected(DependencyObject obj) => (bool)obj.GetValue(IsCellSelectedProperty);
320
-
321
161
  public static void SetIsCellSelected(DependencyObject obj, bool value) => obj.SetValue(IsCellSelectedProperty, value);
322
-
323
162
  public static readonly DependencyProperty IsCellSelectedProperty
324
-
325
163
  = DependencyProperty.RegisterAttached("IsCellSelected", typeof(bool), typeof(DataGridAttachedProperties),
326
-
327
164
  new UIPropertyMetadata(false, OnIsCellSelectedChanged));
328
-
329
165
  private static void OnIsCellSelectedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
330
-
331
- {
166
+ {
332
-
333
167
  if (d is DataGridCell cell)
334
-
335
168
  {
336
-
337
169
  var row = FindVisualParent<DataGridRow>(cell);
338
170
 
339
-
340
-
341
171
  // 同じ行内で複数選択がある状態でそのうち1つを選択し直した場合
342
-
343
172
  // そのセルはCellSelectedChangedが出ない(選択状態は変わらない)ので
344
-
345
173
  // 周りの選択解除だけ伝わってしまいバグる
346
-
347
174
  //row.SetValue(IsCellSelectedProperty, e.NewValue);
348
175
 
349
-
350
-
351
176
  // しかたがないので行内全走査
352
-
353
177
  // 重そうだが100桁くらいなら気にならなかった(1000桁あると数秒止まった^^;
354
-
355
178
  var p = FindVisualParent<DataGridCellsPanel>(cell);
356
-
357
179
  var b = p.Children.Cast<DataGridCell>().Any(x => x.IsSelected);
358
-
359
180
  row.SetValue(IsCellSelectedProperty, b);
360
-
361
181
  }
362
-
363
- }
182
+ }
364
-
365
-
366
183
 
367
184
  private static T FindVisualParent<T>(DependencyObject child) where T : DependencyObject
368
-
369
- {
185
+ {
370
-
371
186
  var parentObject = VisualTreeHelper.GetParent(child);
372
-
373
187
  if (parentObject == null) return null;
374
-
375
188
  if (parentObject is T parent) return parent;
376
-
377
189
  else return FindVisualParent<T>(parentObject);
378
-
379
- }
190
+ }
380
-
381
- }
191
+ }
382
-
383
-
384
192
 
385
193
  public class DataGridBehavior : Behavior<DataGrid>
386
-
387
- {
194
+ {
388
-
389
195
  public static readonly RoutedUICommand UnselectAll = new RoutedUICommand("選択解除", "UnselectAll", typeof(DataGridBehavior));
390
196
 
391
-
392
-
393
197
  protected override void OnAttached()
394
-
395
- {
198
+ {
396
-
397
199
  base.OnAttached();
398
-
399
200
  var commandBinding = new CommandBinding(UnselectAll, Executed);
400
-
401
201
  AssociatedObject.CommandBindings.Add(commandBinding);
402
-
403
- }
202
+ }
404
-
405
-
406
203
 
407
204
  protected override void OnDetaching()
408
-
409
- {
205
+ {
410
-
411
206
  base.OnDetaching();
412
-
413
207
  AssociatedObject.CommandBindings.Clear();
414
-
415
- }
208
+ }
416
-
417
-
418
209
 
419
210
  private void Executed(object target, ExecutedRoutedEventArgs e)
420
-
421
- {
211
+ {
422
-
423
212
  if (AssociatedObject.SelectionUnit == DataGridSelectionUnit.FullRow)
424
-
425
213
  AssociatedObject.UnselectAll();
426
-
427
214
  else
428
-
429
215
  AssociatedObject.UnselectAllCells();
430
-
431
216
  e.Handled = true;
432
-
433
- }
217
+ }
434
-
435
- }
218
+ }
436
-
437
219
  }
438
-
439
220
  ```
440
221
 
441
-
442
-
443
222
  ---
444
223
 
445
-
446
-
447
224
  あれこれいじっていたらいろいろバグを見つけてしまいました^^;
448
225
 
449
-
450
-
451
226
  * `DataGridAttachedProperties`複数選択時未考慮
452
-
453
227
  回答コードを参照してください。
454
-
455
228
  * `Menu`や`ContextMenu`で`DataGrid`に`SelectAll`を使うと以降激重
456
-
457
229
  `SelectAll`だけの(`Style`等をすべてなくして追加コードが一切ない)状態でも再現しますので、WPFのバグっぽいです(意味が分からな過ぎて原因も回避法もわかりません^^;

2

対称性

2021/05/11 08:56

投稿

TN8001
TN8001

スコア9326

test CHANGED
@@ -10,7 +10,7 @@
10
10
 
11
11
  [ApplicationCommands.SelectAll プロパティ (System.Windows.Input) | Microsoft Docs](https://docs.microsoft.com/ja-jp/dotnet/api/system.windows.input.applicationcommands.selectall)
12
12
 
13
- との対性を考えて`RoutedCommand`にしてみました。
13
+ との対性を考えて`RoutedCommand`にしてみました。
14
14
 
15
15
  `View`で完結するのがいい点ですが、`ViewModel`でどうこうしたい場合は逆に扱いにくいです^^;
16
16
 

1

RoutedCommand

2021/05/11 08:56

投稿

TN8001
TN8001

スコア9326

test CHANGED
@@ -2,9 +2,17 @@
2
2
 
3
3
 
4
4
 
5
- `MoveCurrentToPosition(-1)`でもすればいいんじゃないですかね?
5
+ ~~`MoveCurrentToPosition(-1)`でもすればいいんじゃないですかね?~~
6
-
6
+
7
- [CollectionView.MoveCurrentToPosition(Int32) メソッド (System.Windows.Data) | Microsoft Docs](https://docs.microsoft.com/ja-jp/dotnet/api/system.windows.data.collectionview.movecurrenttoposition)
7
+ ~~[CollectionView.MoveCurrentToPosition(Int32) メソッド (System.Windows.Data) | Microsoft Docs](https://docs.microsoft.com/ja-jp/dotnet/api/system.windows.data.collectionview.movecurrenttoposition)~~
8
+
9
+
10
+
11
+ [ApplicationCommands.SelectAll プロパティ (System.Windows.Input) | Microsoft Docs](https://docs.microsoft.com/ja-jp/dotnet/api/system.windows.input.applicationcommands.selectall)
12
+
13
+ との対照性を考えて`RoutedCommand`にしてみました。
14
+
15
+ `View`で完結するのがいい点ですが、`ViewModel`でどうこうしたい場合は逆に扱いにくいです^^;
8
16
 
9
17
 
10
18
 
@@ -34,6 +42,8 @@
34
42
 
35
43
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
36
44
 
45
+ xmlns:b="http://schemas.microsoft.com/xaml/behaviors"
46
+
37
47
  xmlns:v="clr-namespace:Questions337191.Views"
38
48
 
39
49
  xmlns:vm="clr-namespace:Questions337191.ViewModels"
@@ -42,131 +52,173 @@
42
52
 
43
53
  Height="350">
44
54
 
45
-
46
-
47
55
  <Window.DataContext>
48
56
 
49
57
  <vm:MainWindowViewModel />
50
58
 
51
59
  </Window.DataContext>
52
60
 
53
-
54
-
55
- <Grid>
56
-
57
- <Grid.RowDefinitions>
58
-
59
- <RowDefinition Height="50" />
60
-
61
- <RowDefinition />
62
-
63
- <RowDefinition Height="50" />
64
-
65
- </Grid.RowDefinitions>
66
-
67
-
68
-
69
- <Button
70
-
71
- Width="100"
72
-
73
- Margin="5"
74
-
75
- HorizontalAlignment="Left"
76
-
77
- Command="{Binding UnselectCommand}"
78
-
79
- Content="選択解除" />
80
-
81
- <DataGrid
82
-
83
- Grid.Row="1"
84
-
85
- IsSynchronizedWithCurrentItem="True"
86
-
87
- ItemsSource="{Binding MyList}"
88
-
89
- SelectionUnit="Cell">
90
-
91
- <DataGrid.RowStyle>
92
-
93
- <Style TargetType="DataGridRow">
94
-
95
- <Setter Property="Height" Value="20" />
96
-
97
- <Style.Triggers>
98
-
99
- <Trigger Property="v:DataGridAttachedProperties.IsCellSelected" Value="True">
100
-
101
- <Setter Property="Height" Value="40" />
102
-
103
- <Setter Property="Background" Value="Gray" />
104
-
105
- </Trigger>
106
-
107
- </Style.Triggers>
108
-
109
- </Style>
110
-
111
- </DataGrid.RowStyle>
112
-
113
-
114
-
115
- <DataGrid.CellStyle>
116
-
117
- <Style TargetType="DataGridCell">
118
-
119
- <Style.Triggers>
120
-
121
- <Trigger Property="IsSelected" Value="True">
122
-
123
- <Setter Property="Background" Value="LightGray" />
124
-
125
- <Setter Property="v:DataGridAttachedProperties.IsCellSelected" Value="True" />
126
-
127
- </Trigger>
128
-
129
- <Trigger Property="IsSelected" Value="False">
130
-
131
- <Setter Property="v:DataGridAttachedProperties.IsCellSelected" Value="False" />
132
-
133
- </Trigger>
134
-
135
- </Style.Triggers>
136
-
137
- </Style>
138
-
139
- </DataGrid.CellStyle>
140
-
141
-
142
-
143
- <DataGrid.Columns>
144
-
145
- <DataGridTemplateColumn Width="100">
146
-
147
- <DataGridTemplateColumn.CellTemplate>
148
-
149
- <DataTemplate>
150
-
151
- <StackPanel Orientation="Horizontal">
152
-
153
- <TextBox Width="50" Text="コメント" />
154
-
155
- <TextBlock Text="○" />
156
-
157
- </StackPanel>
158
-
159
- </DataTemplate>
160
-
161
- </DataGridTemplateColumn.CellTemplate>
162
-
163
- </DataGridTemplateColumn>
164
-
165
- </DataGrid.Columns>
166
-
167
- </DataGrid>
168
-
169
- </Grid>
61
+ <DockPanel>
62
+
63
+ <!--
64
+
65
+ メニューから呼ぶとなぜか激重になる。
66
+
67
+ 以降ボタンから呼んでもDataGridの左上ボタンでも同じく激重。
68
+
69
+ 意味が分からないw
70
+
71
+ -->
72
+
73
+ <!--<Menu DockPanel.Dock="Top">
74
+
75
+ <MenuItem Header="編集">
76
+
77
+ <MenuItem Command="ApplicationCommands.SelectAll" CommandTarget="{Binding ElementName=dataGrid}" />
78
+
79
+ <MenuItem Command="v:DataGridBehavior.UnselectAll" CommandTarget="{Binding ElementName=dataGrid}" />
80
+
81
+ </MenuItem>
82
+
83
+ </Menu>-->
84
+
85
+ <Grid>
86
+
87
+ <Grid.RowDefinitions>
88
+
89
+ <RowDefinition Height="Auto" />
90
+
91
+ <RowDefinition />
92
+
93
+ </Grid.RowDefinitions>
94
+
95
+ <StackPanel Orientation="Horizontal">
96
+
97
+ <Button
98
+
99
+ MinWidth="100"
100
+
101
+ Margin="5"
102
+
103
+ Command="ApplicationCommands.SelectAll"
104
+
105
+ CommandTarget="{Binding ElementName=dataGrid}"
106
+
107
+ Content="すべて選択" />
108
+
109
+ <Button
110
+
111
+ MinWidth="100"
112
+
113
+ Margin="5"
114
+
115
+ Command="v:DataGridBehavior.UnselectAll"
116
+
117
+ CommandTarget="{Binding ElementName=dataGrid}"
118
+
119
+ Content="選択解除" />
120
+
121
+ </StackPanel>
122
+
123
+
124
+
125
+ <DataGrid
126
+
127
+ x:Name="dataGrid"
128
+
129
+ Grid.Row="1"
130
+
131
+ ItemsSource="{Binding MyList}"
132
+
133
+ SelectionUnit="Cell">
134
+
135
+ <b:Interaction.Behaviors>
136
+
137
+ <v:DataGridBehavior />
138
+
139
+ </b:Interaction.Behaviors>
140
+
141
+ <DataGrid.RowStyle>
142
+
143
+ <Style TargetType="DataGridRow">
144
+
145
+ <Setter Property="Height" Value="20" />
146
+
147
+ <Style.Triggers>
148
+
149
+ <Trigger Property="v:DataGridAttachedProperties.IsCellSelected" Value="True">
150
+
151
+ <Setter Property="Height" Value="40" />
152
+
153
+ <Setter Property="Background" Value="Gray" />
154
+
155
+ </Trigger>
156
+
157
+ </Style.Triggers>
158
+
159
+ </Style>
160
+
161
+ </DataGrid.RowStyle>
162
+
163
+
164
+
165
+ <DataGrid.CellStyle>
166
+
167
+ <Style TargetType="DataGridCell">
168
+
169
+ <Style.Triggers>
170
+
171
+ <Trigger Property="IsSelected" Value="True">
172
+
173
+ <Setter Property="Background" Value="LightGray" />
174
+
175
+ <Setter Property="v:DataGridAttachedProperties.IsCellSelected" Value="True" />
176
+
177
+ </Trigger>
178
+
179
+ <Trigger Property="IsSelected" Value="False">
180
+
181
+ <Setter Property="v:DataGridAttachedProperties.IsCellSelected" Value="False" />
182
+
183
+ </Trigger>
184
+
185
+ </Style.Triggers>
186
+
187
+ </Style>
188
+
189
+ </DataGrid.CellStyle>
190
+
191
+
192
+
193
+ <DataGrid.Columns>
194
+
195
+ <DataGridTemplateColumn Width="100">
196
+
197
+ <DataGridTemplateColumn.CellTemplate>
198
+
199
+ <DataTemplate>
200
+
201
+ <StackPanel Orientation="Horizontal">
202
+
203
+ <TextBox Text="コメント" />
204
+
205
+ <TextBlock Text="○" />
206
+
207
+ </StackPanel>
208
+
209
+ </DataTemplate>
210
+
211
+ </DataGridTemplateColumn.CellTemplate>
212
+
213
+ </DataGridTemplateColumn>
214
+
215
+ </DataGrid.Columns>
216
+
217
+ </DataGrid>
218
+
219
+ </Grid>
220
+
221
+ </DockPanel>
170
222
 
171
223
  </Window>
172
224
 
@@ -178,65 +230,151 @@
178
230
 
179
231
  using Livet;
180
232
 
181
- using Livet.Commands;
182
-
183
233
  using System.Collections.ObjectModel;
184
234
 
185
235
  using System.Linq;
186
236
 
237
+
238
+
239
+ namespace Questions337191.ViewModels
240
+
241
+ {
242
+
243
+ public class MainWindowViewModel : ViewModel
244
+
245
+ {
246
+
247
+ public ObservableCollection<Person> MyList { get; }
248
+
249
+
250
+
251
+ public MainWindowViewModel()
252
+
253
+ {
254
+
255
+ MyList = new ObservableCollection<Person>(
256
+
257
+ Enumerable.Range(1, 10_000).Select(i => new Person
258
+
259
+ {
260
+
261
+ Name = "田中" + i,
262
+
263
+ Age = 20 + i,
264
+
265
+ AuthMember = i % 2 == 0,
266
+
267
+ }));
268
+
269
+ }
270
+
271
+ }
272
+
273
+
274
+
275
+ public class Person
276
+
277
+ {
278
+
279
+ public string Name { get; set; }
280
+
281
+ public int Age { get; set; }
282
+
283
+ public bool AuthMember { get; set; }
284
+
285
+ }
286
+
287
+ }
288
+
289
+ ```
290
+
291
+
292
+
293
+ ```C#
294
+
295
+ using Microsoft.Xaml.Behaviors;
296
+
297
+ using System.Linq;
298
+
187
- using System.Windows.Data;
299
+ using System.Windows;
300
+
301
+ using System.Windows.Controls;
188
302
 
189
303
  using System.Windows.Input;
190
304
 
191
-
305
+ using System.Windows.Media;
192
-
306
+
307
+
308
+
193
- namespace Questions337191.ViewModels
309
+ namespace Questions337191.Views
194
310
 
195
311
  {
196
312
 
197
- public class MainWindowViewModel : ViewModel
313
+ // [wpf - DataGrid SelectionUnit=Cell disables all support for a selected row? - Stack Overflow](https://stackoverflow.com/questions/9489041/datagrid-selectionunit-cell-disables-all-support-for-a-selected-row)
314
+
315
+ public static class DataGridAttachedProperties
198
316
 
199
317
  {
200
318
 
319
+ public static bool GetIsCellSelected(DependencyObject obj) => (bool)obj.GetValue(IsCellSelectedProperty);
320
+
321
+ public static void SetIsCellSelected(DependencyObject obj, bool value) => obj.SetValue(IsCellSelectedProperty, value);
322
+
201
- public ObservableCollection<Person> MyList { get; }
323
+ public static readonly DependencyProperty IsCellSelectedProperty
324
+
202
-
325
+ = DependencyProperty.RegisterAttached("IsCellSelected", typeof(bool), typeof(DataGridAttachedProperties),
326
+
203
- public ICommand UnselectCommand { get; }
327
+ new UIPropertyMetadata(false, OnIsCellSelectedChanged));
204
-
205
-
206
-
328
+
207
- public MainWindowViewModel()
329
+ private static void OnIsCellSelectedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
208
-
330
+
209
- {
331
+ {
210
-
332
+
211
- MyList = new ObservableCollection<Person>(
333
+ if (d is DataGridCell cell)
212
-
213
- Enumerable.Range(1, 5).Select(i => new Person
334
+
214
-
215
- {
335
+ {
336
+
216
-
337
+ var row = FindVisualParent<DataGridRow>(cell);
338
+
339
+
340
+
341
+ // 同じ行内で複数選択がある状態でそのうち1つを選択し直した場合
342
+
343
+ // そのセルはCellSelectedChangedが出ない(選択状態は変わらない)ので
344
+
345
+ // 周りの選択解除だけ伝わってしまいバグる
346
+
347
+ //row.SetValue(IsCellSelectedProperty, e.NewValue);
348
+
349
+
350
+
217
- Name = "田中" + i,
351
+ // しかたがないので行内全走査
218
-
219
- Age = 20 + i,
352
+
220
-
221
- AuthMember = i % 2 == 0
353
+ // 重そうだが100桁くらいなら気にならなかった(1000桁あると数秒止まった^^;
222
-
354
+
223
- }));
355
+ var p = FindVisualParent<DataGridCellsPanel>(cell);
356
+
224
-
357
+ var b = p.Children.Cast<DataGridCell>().Any(x => x.IsSelected);
225
-
226
-
358
+
227
- UnselectCommand = new ViewModelCommand(TestButton);
359
+ row.SetValue(IsCellSelectedProperty, b);
228
-
360
+
229
- }
361
+ }
362
+
230
-
363
+ }
231
-
232
-
364
+
365
+
366
+
233
- public void TestButton()
367
+ private static T FindVisualParent<T>(DependencyObject child) where T : DependencyObject
234
-
368
+
235
- {
369
+ {
236
-
370
+
237
- var cv = CollectionViewSource.GetDefaultView(MyList);
371
+ var parentObject = VisualTreeHelper.GetParent(child);
238
-
372
+
239
- cv.MoveCurrentToPosition(-1);
373
+ if (parentObject == null) return null;
374
+
375
+ if (parentObject is T parent) return parent;
376
+
377
+ else return FindVisualParent<T>(parentObject);
240
378
 
241
379
  }
242
380
 
@@ -244,15 +382,55 @@
244
382
 
245
383
 
246
384
 
247
- public class Person
385
+ public class DataGridBehavior : Behavior<DataGrid>
248
386
 
249
387
  {
250
388
 
389
+ public static readonly RoutedUICommand UnselectAll = new RoutedUICommand("選択解除", "UnselectAll", typeof(DataGridBehavior));
390
+
391
+
392
+
393
+ protected override void OnAttached()
394
+
395
+ {
396
+
397
+ base.OnAttached();
398
+
399
+ var commandBinding = new CommandBinding(UnselectAll, Executed);
400
+
401
+ AssociatedObject.CommandBindings.Add(commandBinding);
402
+
403
+ }
404
+
405
+
406
+
251
- public string Name { get; set; }
407
+ protected override void OnDetaching()
408
+
252
-
409
+ {
410
+
411
+ base.OnDetaching();
412
+
413
+ AssociatedObject.CommandBindings.Clear();
414
+
415
+ }
416
+
417
+
418
+
419
+ private void Executed(object target, ExecutedRoutedEventArgs e)
420
+
421
+ {
422
+
423
+ if (AssociatedObject.SelectionUnit == DataGridSelectionUnit.FullRow)
424
+
253
- public int Age { get; set; }
425
+ AssociatedObject.UnselectAll();
426
+
254
-
427
+ else
428
+
255
- public bool AuthMember { get; set; }
429
+ AssociatedObject.UnselectAllCells();
430
+
431
+ e.Handled = true;
432
+
433
+ }
256
434
 
257
435
  }
258
436
 
@@ -262,72 +440,18 @@
262
440
 
263
441
 
264
442
 
265
- ```C#
266
-
267
- // [wpf - DataGrid SelectionUnit=Cell disables all support for a selected row? - Stack Overflow](https://stackoverflow.com/questions/9489041/datagrid-selectionunit-cell-disables-all-support-for-a-selected-row)
268
-
269
-
270
-
271
- using System.Windows;
272
-
273
- using System.Windows.Controls;
274
-
275
- using System.Windows.Media;
276
-
277
-
278
-
279
- namespace Questions337191.Views
280
-
281
- {
282
-
283
- public static class DataGridAttachedProperties
284
-
285
- {
286
-
287
- public static bool GetIsCellSelected(DependencyObject obj) => (bool)obj.GetValue(IsCellSelectedProperty);
288
-
289
- public static void SetIsCellSelected(DependencyObject obj, bool value) => obj.SetValue(IsCellSelectedProperty, value);
290
-
291
- public static readonly DependencyProperty IsCellSelectedProperty
292
-
293
- = DependencyProperty.RegisterAttached("IsCellSelected", typeof(bool), typeof(DataGridAttachedProperties),
294
-
295
- new UIPropertyMetadata(false, OnIsCellSelectedChanged));
296
-
297
- private static void OnIsCellSelectedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
298
-
299
- {
300
-
301
- if (d is DataGridCell cell)
302
-
303
- {
304
-
305
- var row = FindVisualParent<DataGridRow>(cell);
306
-
307
- row.SetValue(IsCellSelectedProperty, e.NewValue);
308
-
309
- }
310
-
311
- }
312
-
313
-
314
-
315
- private static T FindVisualParent<T>(DependencyObject child) where T : DependencyObject
316
-
317
- {
318
-
319
- var parentObject = VisualTreeHelper.GetParent(child);
320
-
321
- if (parentObject == null) return null;
322
-
323
- if (parentObject is T parent) return parent;
324
-
325
- else return FindVisualParent<T>(parentObject);
326
-
327
- }
328
-
329
- }
330
-
331
- }
332
-
333
- ```
443
+ ---
444
+
445
+
446
+
447
+ あれこれいじっていたらいろいろバグを見つけてしまいました^^;
448
+
449
+
450
+
451
+ * `DataGridAttachedProperties`複数選択時未考慮
452
+
453
+ 回答コードを参照してください。
454
+
455
+ * `Menu`や`ContextMenu`で`DataGrid`に`SelectAll`を使うと以降激重
456
+
457
+ `SelectAll`だけの(`Style`等をすべてなくして追加コードが一切ない)状態でも再現しますので、WPFのバグっぽいです(意味が分からな過ぎて原因も回避法もわかりません^^;