teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

1

見直しキャンペーン中

2023/07/27 13:47

投稿

TN8001
TN8001

スコア10108

answer CHANGED
@@ -1,112 +1,112 @@
1
- > 複数選択情報をプロパティにバインドする方法はないでしょうか?
2
-
3
- `DataGrid`には`SelectedItems`がありますが、残念ながらバインドできません。
4
- [MultiSelector.SelectedItems プロパティ (System.Windows.Controls.Primitives) | Microsoft Docs](https://docs.microsoft.com/ja-jp/dotnet/api/system.windows.controls.primitives.multiselector.selecteditems)
5
-
6
- こちらはどうでしょうか。
7
- [WPFのDataGridで選択された複数のアイテムをバインドするためのビヘイビア - chorus log](http://chorusde.hatenablog.jp/entry/2013/02/28/064747)
8
-
9
- `DataGridRow`の`IsSelected`に個々のアイテムのboolをバインドするような方法も見ますが、仮想化が有効だとまともに動きませんので事実上使えません。
10
-
11
- ```xaml
12
- <Window
13
- x:Class="Questions338172.MainWindow"
14
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
15
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
16
- xmlns:Behaviors="http://schemas.microsoft.com/xaml/behaviors"
17
- xmlns:local="clr-namespace:Questions338172"
18
- Width="800"
19
- Height="450">
20
- <Window.DataContext>
21
- <local:ViewModel />
22
- </Window.DataContext>
23
- <Grid>
24
- <Grid.ColumnDefinitions>
25
- <ColumnDefinition />
26
- <ColumnDefinition />
27
- </Grid.ColumnDefinitions>
28
- <DataGrid AutoGenerateColumns="False" ItemsSource="{Binding Items}">
29
- <Behaviors:Interaction.Behaviors>
30
- <local:BindSelectedItemsBehavior SelectedItems="{Binding SelectedItems}" />
31
- </Behaviors:Interaction.Behaviors>
32
- <DataGrid.Columns>
33
- <DataGridTextColumn
34
- Width="*"
35
- Binding="{Binding Text}"
36
- Header="Text" />
37
- </DataGrid.Columns>
38
- </DataGrid>
39
- <GroupBox Grid.Column="1" Header="Selected Items">
40
- <DockPanel>
41
- <TextBlock DockPanel.Dock="Top" Text="{Binding SelectedItems.Count, StringFormat=Count: {0}}" />
42
- <ListBox DisplayMemberPath="Text" ItemsSource="{Binding SelectedItems}" />
43
- </DockPanel>
44
- </GroupBox>
45
- </Grid>
46
- </Window>
47
- ```
48
-
49
- ```C#
50
- using CommunityToolkit.Mvvm.ComponentModel;
51
- using Microsoft.Xaml.Behaviors;
52
- using System.Collections;
53
- using System.Collections.ObjectModel;
54
- using System.Linq;
55
- using System.Windows;
56
- using System.Windows.Controls;
57
- using System.Windows.Data;
58
-
59
- namespace Questions338172
60
- {
61
- // [WPFのDataGridで選択された複数のアイテムをバインドするためのビヘイビア - chorus log](http://chorusde.hatenablog.jp/entry/2013/02/28/064747)
62
- class BindSelectedItemsBehavior : Behavior<DataGrid>
63
- {
64
- public static DependencyProperty SelectedItemsProperty
65
- = DependencyProperty.Register(nameof(SelectedItems), typeof(IList), typeof(BindSelectedItemsBehavior),
66
- new PropertyMetadata(null));
67
- public IList SelectedItems { get => (IList)GetValue(SelectedItemsProperty); set => SetValue(SelectedItemsProperty, value); }
68
-
69
- protected override void OnAttached() => AssociatedObject.SelectionChanged += SelectionChanged;
70
- protected override void OnDetaching() => AssociatedObject.SelectionChanged -= SelectionChanged;
71
-
72
- private void SelectionChanged(object sender, SelectionChangedEventArgs e)
73
- {
74
- if (SelectedItems == null) return;
75
-
76
- foreach (var addedItem in e.AddedItems)
77
- {
78
- if (addedItem == CollectionView.NewItemPlaceholder) continue;
79
- SelectedItems.Add(addedItem);
80
- }
81
-
82
- foreach (var removedItem in e.RemovedItems)
83
- SelectedItems.Remove(removedItem);
84
- }
85
- }
86
-
87
- class Item
88
- {
89
- public string Text { get; set; }
90
- }
91
-
92
- class ViewModel
93
- {
94
- public ObservableCollection<Item> Items { get; }
95
- public ObservableCollection<Item> SelectedItems { get; }
96
-
97
- public ViewModel()
98
- {
99
- Items = new ObservableCollection<Item>(Enumerable.Range(0, 1_000).Select(x => new Item { Text = $"Item{x}" }));
100
- SelectedItems = new ObservableCollection<Item>();
101
- }
102
- }
103
-
104
- public partial class MainWindow : Window
105
- {
106
- public MainWindow() => InitializeComponent();
107
- }
108
- }
109
- ```
110
-
111
- こちらを使用しています。
1
+ > 複数選択情報をプロパティにバインドする方法はないでしょうか?
2
+
3
+ `DataGrid`には`SelectedItems`がありますが、残念ながらバインドできません。
4
+ [MultiSelector.SelectedItems プロパティ (System.Windows.Controls.Primitives) | Microsoft Docs](https://docs.microsoft.com/ja-jp/dotnet/api/system.windows.controls.primitives.multiselector.selecteditems)
5
+
6
+ こちらはどうでしょうか。
7
+ [WPFのDataGridで選択された複数のアイテムをバインドするためのビヘイビア - chorus log](http://chorusde.hatenablog.jp/entry/2013/02/28/064747)
8
+
9
+ `DataGridRow`の`IsSelected`に個々のアイテムのboolをバインドするような方法も見ますが、仮想化が有効だとまともに動きませんので事実上使えません。
10
+
11
+ ```xml
12
+ <Window
13
+ x:Class="Questions338172.MainWindow"
14
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
15
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
16
+ xmlns:Behaviors="http://schemas.microsoft.com/xaml/behaviors"
17
+ xmlns:local="clr-namespace:Questions338172"
18
+ Width="800"
19
+ Height="450">
20
+ <Window.DataContext>
21
+ <local:ViewModel />
22
+ </Window.DataContext>
23
+ <Grid>
24
+ <Grid.ColumnDefinitions>
25
+ <ColumnDefinition />
26
+ <ColumnDefinition />
27
+ </Grid.ColumnDefinitions>
28
+ <DataGrid AutoGenerateColumns="False" ItemsSource="{Binding Items}">
29
+ <Behaviors:Interaction.Behaviors>
30
+ <local:BindSelectedItemsBehavior SelectedItems="{Binding SelectedItems}" />
31
+ </Behaviors:Interaction.Behaviors>
32
+ <DataGrid.Columns>
33
+ <DataGridTextColumn
34
+ Width="*"
35
+ Binding="{Binding Text}"
36
+ Header="Text" />
37
+ </DataGrid.Columns>
38
+ </DataGrid>
39
+ <GroupBox Grid.Column="1" Header="Selected Items">
40
+ <DockPanel>
41
+ <TextBlock DockPanel.Dock="Top" Text="{Binding SelectedItems.Count, StringFormat=Count: {0}}" />
42
+ <ListBox DisplayMemberPath="Text" ItemsSource="{Binding SelectedItems}" />
43
+ </DockPanel>
44
+ </GroupBox>
45
+ </Grid>
46
+ </Window>
47
+ ```
48
+
49
+ ```cs
50
+ using CommunityToolkit.Mvvm.ComponentModel;
51
+ using Microsoft.Xaml.Behaviors;
52
+ using System.Collections;
53
+ using System.Collections.ObjectModel;
54
+ using System.Linq;
55
+ using System.Windows;
56
+ using System.Windows.Controls;
57
+ using System.Windows.Data;
58
+
59
+ namespace Questions338172
60
+ {
61
+ // [WPFのDataGridで選択された複数のアイテムをバインドするためのビヘイビア - chorus log](http://chorusde.hatenablog.jp/entry/2013/02/28/064747)
62
+ class BindSelectedItemsBehavior : Behavior<DataGrid>
63
+ {
64
+ public static DependencyProperty SelectedItemsProperty
65
+ = DependencyProperty.Register(nameof(SelectedItems), typeof(IList), typeof(BindSelectedItemsBehavior),
66
+ new PropertyMetadata(null));
67
+ public IList SelectedItems { get => (IList)GetValue(SelectedItemsProperty); set => SetValue(SelectedItemsProperty, value); }
68
+
69
+ protected override void OnAttached() => AssociatedObject.SelectionChanged += SelectionChanged;
70
+ protected override void OnDetaching() => AssociatedObject.SelectionChanged -= SelectionChanged;
71
+
72
+ private void SelectionChanged(object sender, SelectionChangedEventArgs e)
73
+ {
74
+ if (SelectedItems == null) return;
75
+
76
+ foreach (var addedItem in e.AddedItems)
77
+ {
78
+ if (addedItem == CollectionView.NewItemPlaceholder) continue;
79
+ SelectedItems.Add(addedItem);
80
+ }
81
+
82
+ foreach (var removedItem in e.RemovedItems)
83
+ SelectedItems.Remove(removedItem);
84
+ }
85
+ }
86
+
87
+ class Item
88
+ {
89
+ public string Text { get; set; }
90
+ }
91
+
92
+ class ViewModel
93
+ {
94
+ public ObservableCollection<Item> Items { get; }
95
+ public ObservableCollection<Item> SelectedItems { get; }
96
+
97
+ public ViewModel()
98
+ {
99
+ Items = new ObservableCollection<Item>(Enumerable.Range(0, 1_000).Select(x => new Item { Text = $"Item{x}" }));
100
+ SelectedItems = new ObservableCollection<Item>();
101
+ }
102
+ }
103
+
104
+ public partial class MainWindow : Window
105
+ {
106
+ public MainWindow() => InitializeComponent();
107
+ }
108
+ }
109
+ ```
110
+
111
+ こちらを使用しています。
112
112
  [NuGet Gallery | Microsoft.Xaml.Behaviors.Wpf 1.1.31](https://www.nuget.org/packages/Microsoft.Xaml.Behaviors.Wpf/1.1.31)