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

回答編集履歴

1

見直しキャンペーン中

2023/07/28 14:26

投稿

TN8001
TN8001

スコア10180

answer CHANGED
@@ -1,152 +1,152 @@
1
- 参考コードがある場合は、質問に**明示**してください。
2
- [(WPF) SelectedItems をViewModelで取得する - まめ - たんたんめん](https://p4j4.hatenablog.com/entry/2018/03/28/204953)
3
-
4
-
5
- > 以下のコード内の「SelectedStudents」にアイテム群が入らずにnullのままです。
6
-
7
- `SelectedItemsBehavior`では、`SelectedItems`が`IEnumerable`と定義されています(実体は`object[]`です)
8
- `ObservableCollection<Student>`にはキャストできませんので`null`になります。
9
-
10
- ViewModel側もそれに合わせて`IEnumerable`とする必要があります。
11
-
12
- そもそもこのビヘイビアは選択が変わるたびに、`SelectedItems`が丸ごと入れ替わります。
13
- そのため`ObservableCollection`の意味はありません。
14
-
15
- そしてこのコードではViewでの変更しか感知できません(`TwoWay`指定になっていますが^^;
16
-
17
- ```xaml
18
- <Window
19
- x:Class="Questions351149.MainWindow"
20
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
21
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
22
- xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
23
- xmlns:local="clr-namespace:Questions351149"
24
- Width="800"
25
- Height="450">
26
- <Window.DataContext>
27
- <local:BM_StudentListViewModel />
28
- </Window.DataContext>
29
- <DockPanel Margin="10">
30
- <Button
31
- MinWidth="60"
32
- Margin="10"
33
- HorizontalAlignment="Right"
34
- Command="{Binding OkButton}"
35
- Content="読込"
36
- DockPanel.Dock="Bottom" />
37
-
38
- <ListView ItemsSource="{Binding Students}" SelectionMode="Multiple">
39
- <i:Interaction.Behaviors>
40
- <local:SelectedItemsBehavior SelectedItems="{Binding SelectedStudents}" />
41
- </i:Interaction.Behaviors>
42
- <ListView.View>
43
- <GridView>
44
- <GridViewColumn DisplayMemberBinding="{Binding Id}" Header="番号" />
45
- <GridViewColumn DisplayMemberBinding="{Binding Name}" Header="氏名" />
46
- <GridViewColumn DisplayMemberBinding="{Binding Kana}" Header="フリガナ" />
47
- </GridView>
48
- </ListView.View>
49
- </ListView>
50
- </DockPanel>
51
- </Window>
52
- ```
53
-
54
- ```C#
55
- using Microsoft.Xaml.Behaviors;
56
- using Prism.Commands;
57
- using Prism.Mvvm;
58
- using System.Collections;
59
- using System.Collections.ObjectModel;
60
- using System.Diagnostics;
61
- using System.Linq;
62
- using System.Windows;
63
- using System.Windows.Controls;
64
- using System.Windows.Controls.Primitives;
65
-
66
- namespace Questions351149
67
- {
68
- [TypeConstraint(typeof(Selector))]
69
- public class SelectedItemsBehavior : Behavior<Selector>
70
- {
71
- public static readonly DependencyProperty SelectedItemsProperty =
72
- DependencyProperty.Register(nameof(SelectedItems),
73
- typeof(IEnumerable),
74
- typeof(SelectedItemsBehavior),
75
- new FrameworkPropertyMetadata(null,
76
- FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
77
- public IEnumerable SelectedItems
78
- {
79
- get => (IEnumerable)GetValue(SelectedItemsProperty);
80
- set => SetValue(SelectedItemsProperty, value);
81
- }
82
- protected override void OnAttached()
83
- {
84
- base.OnAttached();
85
- AssociatedObject.SelectionChanged += SelectionChanged;
86
- }
87
- protected override void OnDetaching()
88
- {
89
- AssociatedObject.SelectionChanged -= SelectionChanged;
90
- base.OnDetaching();
91
- }
92
- private void SelectionChanged(object sender, SelectionChangedEventArgs args)
93
- {
94
- dynamic selector = AssociatedObject;
95
- SelectedItems = Enumerable.ToArray(selector.SelectedItems);
96
- }
97
- }
98
-
99
- public class BM_StudentListViewModel : BindableBase
100
- {
101
- public ObservableCollection<Student> Students { get; }
102
-
103
- private IEnumerable _selectedStudents;
104
- public IEnumerable SelectedStudents
105
- {
106
- get => _selectedStudents;
107
- set => SetProperty(ref _selectedStudents, value);
108
- }
109
-
110
- public DelegateCommand OkButton { get; }
111
-
112
-
113
- public BM_StudentListViewModel()
114
- {
115
- Students = new ObservableCollection<Student>(Enumerable.Range(0, 50).Select(_ => new Student()));
116
- OkButton = new DelegateCommand(OkButtonExecute);
117
- }
118
-
119
- private void OkButtonExecute()
120
- {
121
- if (SelectedStudents == null) return;
122
- foreach (Student s in SelectedStudents)
123
- {
124
- Debug.WriteLine(s);
125
- }
126
- Debug.WriteLine("");
127
- }
128
- }
129
-
130
- public class Student
131
- {
132
- public string Id { get; }
133
- public string Name { get; }
134
- public string Kana { get; }
135
-
136
- private static int no;
137
- public Student()
138
- {
139
- Id = $"Id{++no}";
140
- Name = $"Name{no}";
141
- Kana = $"Kana{no}";
142
- }
143
-
144
- public override string ToString() => $"Id:{Id}, Name:{Name}, Kana:{Kana}";
145
- }
146
-
147
- public partial class MainWindow : Window
148
- {
149
- public MainWindow() => InitializeComponent();
150
- }
151
- }
1
+ 参考コードがある場合は、質問に**明示**してください。
2
+ [(WPF) SelectedItems をViewModelで取得する - まめ - たんたんめん](https://p4j4.hatenablog.com/entry/2018/03/28/204953)
3
+
4
+
5
+ > 以下のコード内の「SelectedStudents」にアイテム群が入らずにnullのままです。
6
+
7
+ `SelectedItemsBehavior`では、`SelectedItems`が`IEnumerable`と定義されています(実体は`object[]`です)
8
+ `ObservableCollection<Student>`にはキャストできませんので`null`になります。
9
+
10
+ ViewModel側もそれに合わせて`IEnumerable`とする必要があります。
11
+
12
+ そもそもこのビヘイビアは選択が変わるたびに、`SelectedItems`が丸ごと入れ替わります。
13
+ そのため`ObservableCollection`の意味はありません。
14
+
15
+ そしてこのコードではViewでの変更しか感知できません(`TwoWay`指定になっていますが^^;
16
+
17
+ ```xml
18
+ <Window
19
+ x:Class="Questions351149.MainWindow"
20
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
21
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
22
+ xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
23
+ xmlns:local="clr-namespace:Questions351149"
24
+ Width="800"
25
+ Height="450">
26
+ <Window.DataContext>
27
+ <local:BM_StudentListViewModel />
28
+ </Window.DataContext>
29
+ <DockPanel Margin="10">
30
+ <Button
31
+ MinWidth="60"
32
+ Margin="10"
33
+ HorizontalAlignment="Right"
34
+ Command="{Binding OkButton}"
35
+ Content="読込"
36
+ DockPanel.Dock="Bottom" />
37
+
38
+ <ListView ItemsSource="{Binding Students}" SelectionMode="Multiple">
39
+ <i:Interaction.Behaviors>
40
+ <local:SelectedItemsBehavior SelectedItems="{Binding SelectedStudents}" />
41
+ </i:Interaction.Behaviors>
42
+ <ListView.View>
43
+ <GridView>
44
+ <GridViewColumn DisplayMemberBinding="{Binding Id}" Header="番号" />
45
+ <GridViewColumn DisplayMemberBinding="{Binding Name}" Header="氏名" />
46
+ <GridViewColumn DisplayMemberBinding="{Binding Kana}" Header="フリガナ" />
47
+ </GridView>
48
+ </ListView.View>
49
+ </ListView>
50
+ </DockPanel>
51
+ </Window>
52
+ ```
53
+
54
+ ```cs
55
+ using Microsoft.Xaml.Behaviors;
56
+ using Prism.Commands;
57
+ using Prism.Mvvm;
58
+ using System.Collections;
59
+ using System.Collections.ObjectModel;
60
+ using System.Diagnostics;
61
+ using System.Linq;
62
+ using System.Windows;
63
+ using System.Windows.Controls;
64
+ using System.Windows.Controls.Primitives;
65
+
66
+ namespace Questions351149
67
+ {
68
+ [TypeConstraint(typeof(Selector))]
69
+ public class SelectedItemsBehavior : Behavior<Selector>
70
+ {
71
+ public static readonly DependencyProperty SelectedItemsProperty =
72
+ DependencyProperty.Register(nameof(SelectedItems),
73
+ typeof(IEnumerable),
74
+ typeof(SelectedItemsBehavior),
75
+ new FrameworkPropertyMetadata(null,
76
+ FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
77
+ public IEnumerable SelectedItems
78
+ {
79
+ get => (IEnumerable)GetValue(SelectedItemsProperty);
80
+ set => SetValue(SelectedItemsProperty, value);
81
+ }
82
+ protected override void OnAttached()
83
+ {
84
+ base.OnAttached();
85
+ AssociatedObject.SelectionChanged += SelectionChanged;
86
+ }
87
+ protected override void OnDetaching()
88
+ {
89
+ AssociatedObject.SelectionChanged -= SelectionChanged;
90
+ base.OnDetaching();
91
+ }
92
+ private void SelectionChanged(object sender, SelectionChangedEventArgs args)
93
+ {
94
+ dynamic selector = AssociatedObject;
95
+ SelectedItems = Enumerable.ToArray(selector.SelectedItems);
96
+ }
97
+ }
98
+
99
+ public class BM_StudentListViewModel : BindableBase
100
+ {
101
+ public ObservableCollection<Student> Students { get; }
102
+
103
+ private IEnumerable _selectedStudents;
104
+ public IEnumerable SelectedStudents
105
+ {
106
+ get => _selectedStudents;
107
+ set => SetProperty(ref _selectedStudents, value);
108
+ }
109
+
110
+ public DelegateCommand OkButton { get; }
111
+
112
+
113
+ public BM_StudentListViewModel()
114
+ {
115
+ Students = new ObservableCollection<Student>(Enumerable.Range(0, 50).Select(_ => new Student()));
116
+ OkButton = new DelegateCommand(OkButtonExecute);
117
+ }
118
+
119
+ private void OkButtonExecute()
120
+ {
121
+ if (SelectedStudents == null) return;
122
+ foreach (Student s in SelectedStudents)
123
+ {
124
+ Debug.WriteLine(s);
125
+ }
126
+ Debug.WriteLine("");
127
+ }
128
+ }
129
+
130
+ public class Student
131
+ {
132
+ public string Id { get; }
133
+ public string Name { get; }
134
+ public string Kana { get; }
135
+
136
+ private static int no;
137
+ public Student()
138
+ {
139
+ Id = $"Id{++no}";
140
+ Name = $"Name{no}";
141
+ Kana = $"Kana{no}";
142
+ }
143
+
144
+ public override string ToString() => $"Id:{Id}, Name:{Name}, Kana:{Kana}";
145
+ }
146
+
147
+ public partial class MainWindow : Window
148
+ {
149
+ public MainWindow() => InitializeComponent();
150
+ }
151
+ }
152
152
  ```