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

回答編集履歴

1

見直しキャンペーン中

2023/07/17 05:45

投稿

TN8001
TN8001

スコア10111

answer CHANGED
@@ -1,226 +1,226 @@
1
- ちょっと苦労されているようなので、サンプルを書いてみました。
2
- NuGetで`Prism.Core`を入れてあります。
3
- ```C#
4
- using System.Collections.ObjectModel;
5
- using System.ComponentModel;
6
- using System.Windows;
7
- using System.Windows.Data;
8
- using Prism.Commands;
9
- using Prism.Mvvm;
10
-
11
- namespace Questions222623
12
- {
13
- internal class MainViewModel
14
- {
15
- public class ItemViewModel : BindableBase
16
- {
17
- private bool _Selected;
18
- public bool Selected { get => _Selected; set => SetProperty(ref _Selected, value); }
19
-
20
- private string _Name;
21
- public string Name { get => _Name; set => SetProperty(ref _Name, value); }
22
- }
23
-
24
- public ObservableCollection<ItemViewModel> Items { get; }
25
- public ICollectionView LeftView { get; }
26
- public ICollectionView RightView { get; }
27
- public DelegateCommand<ItemViewModel> Left2RightCommand { get; }
28
- public DelegateCommand<ItemViewModel> Right2LeftCommand { get; }
29
-
30
- public MainViewModel()
31
- {
32
- Items = new ObservableCollection<ItemViewModel>
33
- {
34
- new ItemViewModel() { Name = "C1", Selected = true },
35
- new ItemViewModel() { Name = "C2", Selected = false },
36
- new ItemViewModel() { Name = "C3", Selected = true },
37
- new ItemViewModel() { Name = "C4", Selected = true },
38
- new ItemViewModel() { Name = "C5", Selected = false },
39
- new ItemViewModel() { Name = "C6", Selected = true },
40
- };
41
-
42
- var cvs = new CollectionViewSource { Source = Items, };
43
- cvs.IsLiveFilteringRequested = true; // 変更があったときにフィルターを即時反映
44
- cvs.LiveFilteringProperties.Add(nameof(ItemViewModel.Selected)); // 変更を監視するプロパティ名
45
- LeftView = cvs.View;
46
- LeftView.Filter = x => (x as ItemViewModel).Selected == true;
47
-
48
- cvs = new CollectionViewSource { Source = Items, };
49
- cvs.IsLiveFilteringRequested = true;
50
- cvs.LiveFilteringProperties.Add(nameof(ItemViewModel.Selected));
51
- RightView = cvs.View;
52
- RightView.Filter = x => (x as ItemViewModel).Selected == false;
53
-
54
- Left2RightCommand = new DelegateCommand<ItemViewModel>(Left2rightCommandExecute);
55
- Right2LeftCommand = new DelegateCommand<ItemViewModel>((item) => { if(item != null) item.Selected = true; }); // ラムダでもよい
56
- }
57
-
58
- private void Left2rightCommandExecute(ItemViewModel item)
59
- {
60
- if(item != null)
61
- item.Selected = false;
62
- }
63
- }
64
-
65
- public partial class MainWindow : Window
66
- {
67
- public MainWindow() => InitializeComponent();
68
- }
69
- }
70
- ```
71
- ```xaml
72
- <Window
73
- x:Class="Questions222623.MainWindow"
74
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
75
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
76
- xmlns:local="clr-namespace:Questions222623"
77
- Title="MainWindow"
78
- Width="800"
79
- Height="450">
80
- <Window.DataContext>
81
- <local:MainViewModel />
82
- </Window.DataContext>
83
- <Grid>
84
- <Grid.ColumnDefinitions>
85
- <ColumnDefinition />
86
- <ColumnDefinition Width="Auto" />
87
- <ColumnDefinition />
88
- </Grid.ColumnDefinitions>
89
- <ListBox
90
- x:Name="listBox"
91
- DisplayMemberPath="Name"
92
- ItemsSource="{Binding LeftView}" />
93
- <StackPanel Grid.Column="1" VerticalAlignment="Center">
94
- <Button
95
- Margin="5"
96
- Padding="5"
97
- Command="{Binding Left2RightCommand}"
98
- CommandParameter="{Binding SelectedItem, ElementName=listBox}"
99
- Content="→" />
100
- <Button
101
- Margin="5"
102
- Padding="5"
103
- Command="{Binding Right2LeftCommand}"
104
- CommandParameter="{Binding SelectedItem, ElementName=listBox1}"
105
- Content="←" />
106
- </StackPanel>
107
- <ListBox
108
- x:Name="listBox1"
109
- Grid.Column="2"
110
- DisplayMemberPath="Name"
111
- ItemsSource="{Binding RightView}" />
112
- </Grid>
113
- </Window>
114
- ```
115
- ![イメージ説明](2d99cba7cf1f91078346bcf5a4292aa4.png)
116
- こういうイメージであっていますでしょうか?
117
-
118
- ---
119
-
120
- 別解としてドラッグ&ドロップでの移動例も作ってみました。
121
- NuGetで`Prism.Core` `gong-wpf-dragdrop`を入れてあります。
122
- ```C#
123
- using System.Collections;
124
- using System.Collections.ObjectModel;
125
- using System.Windows;
126
- using GongSolutions.Wpf.DragDrop;
127
- using Prism.Mvvm;
128
-
129
- namespace Questions222623
130
- {
131
- internal class MainViewModel : IDropTarget
132
- {
133
- public class ItemViewModel : BindableBase
134
- {
135
- private string _Name;
136
- public string Name { get => _Name; set => SetProperty(ref _Name, value); }
137
- }
138
-
139
- public ObservableCollection<ItemViewModel> SelectedItems { get; }
140
- public ObservableCollection<ItemViewModel> UnselectedItems { get; }
141
-
142
- private readonly DefaultDropHandler defaultDropHandler = new DefaultDropHandler();
143
-
144
- public MainViewModel()
145
- {
146
- SelectedItems = new ObservableCollection<ItemViewModel>
147
- {
148
- new ItemViewModel() { Name = "C1", },
149
- new ItemViewModel() { Name = "C3", },
150
- new ItemViewModel() { Name = "C4", },
151
- new ItemViewModel() { Name = "C6", },
152
- };
153
- UnselectedItems = new ObservableCollection<ItemViewModel>
154
- {
155
- new ItemViewModel() { Name = "C2", },
156
- new ItemViewModel() { Name = "C5", },
157
- };
158
- }
159
-
160
- void IDropTarget.DragOver(IDropInfo dropInfo)
161
- {
162
- if(dropInfo.Data is ItemViewModel)
163
- {
164
- dropInfo.DropTargetAdorner = DropTargetAdorners.Insert;
165
- dropInfo.Effects = DragDropEffects.Move;
166
- }
167
- }
168
- void IDropTarget.Drop(IDropInfo dropInfo)
169
- {
170
- if(dropInfo.Data is ItemViewModel item)
171
- {
172
- if(dropInfo.DragInfo.SourceCollection != dropInfo.TargetCollection)
173
- {
174
- ((IList)dropInfo.DragInfo.SourceCollection).Remove(item);
175
- ((IList)dropInfo.TargetCollection).Insert(dropInfo.InsertIndex, item);
176
- }
177
- else
178
- {
179
- defaultDropHandler.Drop(dropInfo);
180
- }
181
- }
182
- }
183
- }
184
- public partial class MainWindow : Window
185
- {
186
- public MainWindow() => InitializeComponent();
187
- }
188
- }
189
- ```
190
-
191
- ```xaml
192
- <Window
193
- x:Class="Questions222623.MainWindow"
194
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
195
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
196
- xmlns:dd="urn:gong-wpf-dragdrop"
197
- xmlns:local="clr-namespace:Questions222623"
198
- Title="MainWindow"
199
- Width="800"
200
- Height="450">
201
- <Window.DataContext>
202
- <local:MainViewModel />
203
- </Window.DataContext>
204
- <Grid>
205
- <Grid.ColumnDefinitions>
206
- <ColumnDefinition />
207
- <ColumnDefinition />
208
- </Grid.ColumnDefinitions>
209
- <ListBox
210
- dd:DragDrop.DropHandler="{Binding}"
211
- dd:DragDrop.IsDragSource="True"
212
- dd:DragDrop.IsDropTarget="True"
213
- DisplayMemberPath="Name"
214
- ItemsSource="{Binding SelectedItems}" />
215
- <ListBox
216
- Grid.Column="1"
217
- dd:DragDrop.DropHandler="{Binding}"
218
- dd:DragDrop.IsDragSource="True"
219
- dd:DragDrop.IsDropTarget="True"
220
- DisplayMemberPath="Name"
221
- ItemsSource="{Binding UnselectedItems}" />
222
- </Grid>
223
- </Window>
224
- ```
225
- ![イメージ説明](dc019f2128de1fbd553a69bfc6e24fb5.png)
1
+ ちょっと苦労されているようなので、サンプルを書いてみました。
2
+ NuGetで`Prism.Core`を入れてあります。
3
+ ```cs
4
+ using System.Collections.ObjectModel;
5
+ using System.ComponentModel;
6
+ using System.Windows;
7
+ using System.Windows.Data;
8
+ using Prism.Commands;
9
+ using Prism.Mvvm;
10
+
11
+ namespace Questions222623
12
+ {
13
+ internal class MainViewModel
14
+ {
15
+ public class ItemViewModel : BindableBase
16
+ {
17
+ private bool _Selected;
18
+ public bool Selected { get => _Selected; set => SetProperty(ref _Selected, value); }
19
+
20
+ private string _Name;
21
+ public string Name { get => _Name; set => SetProperty(ref _Name, value); }
22
+ }
23
+
24
+ public ObservableCollection<ItemViewModel> Items { get; }
25
+ public ICollectionView LeftView { get; }
26
+ public ICollectionView RightView { get; }
27
+ public DelegateCommand<ItemViewModel> Left2RightCommand { get; }
28
+ public DelegateCommand<ItemViewModel> Right2LeftCommand { get; }
29
+
30
+ public MainViewModel()
31
+ {
32
+ Items = new ObservableCollection<ItemViewModel>
33
+ {
34
+ new ItemViewModel() { Name = "C1", Selected = true },
35
+ new ItemViewModel() { Name = "C2", Selected = false },
36
+ new ItemViewModel() { Name = "C3", Selected = true },
37
+ new ItemViewModel() { Name = "C4", Selected = true },
38
+ new ItemViewModel() { Name = "C5", Selected = false },
39
+ new ItemViewModel() { Name = "C6", Selected = true },
40
+ };
41
+
42
+ var cvs = new CollectionViewSource { Source = Items, };
43
+ cvs.IsLiveFilteringRequested = true; // 変更があったときにフィルターを即時反映
44
+ cvs.LiveFilteringProperties.Add(nameof(ItemViewModel.Selected)); // 変更を監視するプロパティ名
45
+ LeftView = cvs.View;
46
+ LeftView.Filter = x => (x as ItemViewModel).Selected == true;
47
+
48
+ cvs = new CollectionViewSource { Source = Items, };
49
+ cvs.IsLiveFilteringRequested = true;
50
+ cvs.LiveFilteringProperties.Add(nameof(ItemViewModel.Selected));
51
+ RightView = cvs.View;
52
+ RightView.Filter = x => (x as ItemViewModel).Selected == false;
53
+
54
+ Left2RightCommand = new DelegateCommand<ItemViewModel>(Left2rightCommandExecute);
55
+ Right2LeftCommand = new DelegateCommand<ItemViewModel>((item) => { if(item != null) item.Selected = true; }); // ラムダでもよい
56
+ }
57
+
58
+ private void Left2rightCommandExecute(ItemViewModel item)
59
+ {
60
+ if(item != null)
61
+ item.Selected = false;
62
+ }
63
+ }
64
+
65
+ public partial class MainWindow : Window
66
+ {
67
+ public MainWindow() => InitializeComponent();
68
+ }
69
+ }
70
+ ```
71
+ ```xml
72
+ <Window
73
+ x:Class="Questions222623.MainWindow"
74
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
75
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
76
+ xmlns:local="clr-namespace:Questions222623"
77
+ Title="MainWindow"
78
+ Width="800"
79
+ Height="450">
80
+ <Window.DataContext>
81
+ <local:MainViewModel />
82
+ </Window.DataContext>
83
+ <Grid>
84
+ <Grid.ColumnDefinitions>
85
+ <ColumnDefinition />
86
+ <ColumnDefinition Width="Auto" />
87
+ <ColumnDefinition />
88
+ </Grid.ColumnDefinitions>
89
+ <ListBox
90
+ x:Name="listBox"
91
+ DisplayMemberPath="Name"
92
+ ItemsSource="{Binding LeftView}" />
93
+ <StackPanel Grid.Column="1" VerticalAlignment="Center">
94
+ <Button
95
+ Margin="5"
96
+ Padding="5"
97
+ Command="{Binding Left2RightCommand}"
98
+ CommandParameter="{Binding SelectedItem, ElementName=listBox}"
99
+ Content="→" />
100
+ <Button
101
+ Margin="5"
102
+ Padding="5"
103
+ Command="{Binding Right2LeftCommand}"
104
+ CommandParameter="{Binding SelectedItem, ElementName=listBox1}"
105
+ Content="←" />
106
+ </StackPanel>
107
+ <ListBox
108
+ x:Name="listBox1"
109
+ Grid.Column="2"
110
+ DisplayMemberPath="Name"
111
+ ItemsSource="{Binding RightView}" />
112
+ </Grid>
113
+ </Window>
114
+ ```
115
+ ![イメージ説明](2d99cba7cf1f91078346bcf5a4292aa4.png)
116
+ こういうイメージであっていますでしょうか?
117
+
118
+ ---
119
+
120
+ 別解としてドラッグ&ドロップでの移動例も作ってみました。
121
+ NuGetで`Prism.Core` `gong-wpf-dragdrop`を入れてあります。
122
+ ```cs
123
+ using System.Collections;
124
+ using System.Collections.ObjectModel;
125
+ using System.Windows;
126
+ using GongSolutions.Wpf.DragDrop;
127
+ using Prism.Mvvm;
128
+
129
+ namespace Questions222623
130
+ {
131
+ internal class MainViewModel : IDropTarget
132
+ {
133
+ public class ItemViewModel : BindableBase
134
+ {
135
+ private string _Name;
136
+ public string Name { get => _Name; set => SetProperty(ref _Name, value); }
137
+ }
138
+
139
+ public ObservableCollection<ItemViewModel> SelectedItems { get; }
140
+ public ObservableCollection<ItemViewModel> UnselectedItems { get; }
141
+
142
+ private readonly DefaultDropHandler defaultDropHandler = new DefaultDropHandler();
143
+
144
+ public MainViewModel()
145
+ {
146
+ SelectedItems = new ObservableCollection<ItemViewModel>
147
+ {
148
+ new ItemViewModel() { Name = "C1", },
149
+ new ItemViewModel() { Name = "C3", },
150
+ new ItemViewModel() { Name = "C4", },
151
+ new ItemViewModel() { Name = "C6", },
152
+ };
153
+ UnselectedItems = new ObservableCollection<ItemViewModel>
154
+ {
155
+ new ItemViewModel() { Name = "C2", },
156
+ new ItemViewModel() { Name = "C5", },
157
+ };
158
+ }
159
+
160
+ void IDropTarget.DragOver(IDropInfo dropInfo)
161
+ {
162
+ if(dropInfo.Data is ItemViewModel)
163
+ {
164
+ dropInfo.DropTargetAdorner = DropTargetAdorners.Insert;
165
+ dropInfo.Effects = DragDropEffects.Move;
166
+ }
167
+ }
168
+ void IDropTarget.Drop(IDropInfo dropInfo)
169
+ {
170
+ if(dropInfo.Data is ItemViewModel item)
171
+ {
172
+ if(dropInfo.DragInfo.SourceCollection != dropInfo.TargetCollection)
173
+ {
174
+ ((IList)dropInfo.DragInfo.SourceCollection).Remove(item);
175
+ ((IList)dropInfo.TargetCollection).Insert(dropInfo.InsertIndex, item);
176
+ }
177
+ else
178
+ {
179
+ defaultDropHandler.Drop(dropInfo);
180
+ }
181
+ }
182
+ }
183
+ }
184
+ public partial class MainWindow : Window
185
+ {
186
+ public MainWindow() => InitializeComponent();
187
+ }
188
+ }
189
+ ```
190
+
191
+ ```xml
192
+ <Window
193
+ x:Class="Questions222623.MainWindow"
194
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
195
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
196
+ xmlns:dd="urn:gong-wpf-dragdrop"
197
+ xmlns:local="clr-namespace:Questions222623"
198
+ Title="MainWindow"
199
+ Width="800"
200
+ Height="450">
201
+ <Window.DataContext>
202
+ <local:MainViewModel />
203
+ </Window.DataContext>
204
+ <Grid>
205
+ <Grid.ColumnDefinitions>
206
+ <ColumnDefinition />
207
+ <ColumnDefinition />
208
+ </Grid.ColumnDefinitions>
209
+ <ListBox
210
+ dd:DragDrop.DropHandler="{Binding}"
211
+ dd:DragDrop.IsDragSource="True"
212
+ dd:DragDrop.IsDropTarget="True"
213
+ DisplayMemberPath="Name"
214
+ ItemsSource="{Binding SelectedItems}" />
215
+ <ListBox
216
+ Grid.Column="1"
217
+ dd:DragDrop.DropHandler="{Binding}"
218
+ dd:DragDrop.IsDragSource="True"
219
+ dd:DragDrop.IsDropTarget="True"
220
+ DisplayMemberPath="Name"
221
+ ItemsSource="{Binding UnselectedItems}" />
222
+ </Grid>
223
+ </Window>
224
+ ```
225
+ ![イメージ説明](dc019f2128de1fbd553a69bfc6e24fb5.png)
226
226
  コードが長くなると本質がわかりにくくなるため、`CollectionViewSource`を使わずシンプルに`SelectedItems` `UnselectedItems`と2つに分けましたが、もちろん使っても構いません。