質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

Q&A

解決済

1回答

3254閲覧

ListViewにおいて複数選択したアイテムを、コードビハインドを使わずに取得したい。

yshr3

総合スコア4

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

1グッド

0クリップ

投稿2021/07/25 09:05

質問

ListViewにおいて複数選択した場合に、コードビハインドを使わずにアイテム群を取得したいです。
ビヘイビアを使用して取得しようと試みているのですが、複数選択した場合でも、
以下のコード内の「SelectedStudents」にアイテム群が入らずにnullのままです。
原因を教えていただけますようよろしくお願いいたします。

BM_StudentList.xaml(一部抜粋)

C#

1<UserControl x:Class="Presentation.BillingManagement.BM_StudentList" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 xmlns:i="http://schemas.microsoft.com/xaml/behaviors" 5 xmlns:prism="http://prismlibrary.com/" 6 xmlns:local="clr-namespace:Presentation.BillingManagement" 7 prism:ViewModelLocator.AutoWireViewModel="True"> 8 <StackPanel Margin="10" > 9 <ListView ItemsSource="{Binding Students}" 10 Width="Auto" HorizontalContentAlignment="Stretch"> 11 <i:Interaction.Behaviors> 12 <local:SelectedItemsBehavior SelectedItems="{Binding SelectedStudents}" /> 13 </i:Interaction.Behaviors> 14 <ListView.View > 15 <GridView > 16 <GridViewColumn Header="番号" DisplayMemberBinding="{Binding Id}" Width="50"/> 17 <GridViewColumn Header="氏名" DisplayMemberBinding="{Binding Name}" Width="Auto" /> 18 <GridViewColumn Header="フリガナ" DisplayMemberBinding="{Binding Kana}" Width="Auto" /> 19 </GridView> 20 </ListView.View> 21 </ListView> 22 <Button Content="読込" Command="{Binding OkButton}" 23 HorizontalAlignment="Right" Width="60" Margin="10"/> 24 </StackPanel> 25</UserControl>

BM_StudentListViewModel.cs(一部抜粋)

C#

1using Prism.Commands; 2using Prism.Mvvm; 3using Prism.Services.Dialogs; 4using System; 5using System.Collections.ObjectModel; 6 7namespace Presentation.BillingManagement 8{ 9 public class BM_StudentListViewModel : BindableBase, IDialogAware 10 { 11 private StudentUsecase _usecase; 12 public BM_StudentListViewModel(StudentUsecase usecase) 13 { 14 _usecase = usecase; 15 Students = _usecase.GetStudents(); 16 OkButton = new DelegateCommand(OkButtonExecute); 17 } 18 19 private ObservableCollection<Student> _students 20 = new ObservableCollection<Student>(); 21 public ObservableCollection<Student> Students 22 { 23 get { return _students; } 24 set { SetProperty(ref _students, value); } 25 } 26 27 private ObservableCollection<Student> _selectedStudents; 28 public ObservableCollection<Student> SelectedStudents 29 { 30 get { return _selectedStudents; } 31 set { SetProperty(ref _selectedStudents, value); } 32 } 33 34 public DelegateCommand OkButton { get; } 35 private void OkButtonExecute() 36 { 37 var r = ButtonResult.OK; 38 if (SelectedStudents == null) 39 { 40 r = ButtonResult.None; 41 } 42 var p = new DialogParameters(); 43 p.Add(nameof(SelectedStudents), SelectedStudents); 44 RequestClose.Invoke(new DialogResult(r, p)); 45 } 46 } 47} 48

BM_Behavior.cs

C#

1using Microsoft.Xaml.Behaviors; 2using System.Collections; 3using System.Linq; 4using System.Windows; 5using System.Windows.Controls; 6using System.Windows.Controls.Primitives; 7 8namespace Presentation.BillingManagement 9{ 10 [TypeConstraint(typeof(Selector))] 11 public class SelectedItemsBehavior : Behavior<Selector> 12 { 13 public static readonly DependencyProperty SelectedItemsProperty = 14 DependencyProperty.Register("SelectedItems", 15 typeof(IEnumerable), 16 typeof(SelectedItemsBehavior), 17 new FrameworkPropertyMetadata(null, 18 FrameworkPropertyMetadataOptions.BindsTwoWayByDefault)); 19 public IEnumerable SelectedItems 20 { 21 get => (IEnumerable)GetValue(SelectedItemsProperty); 22 set => SetValue(SelectedItemsProperty, value); 23 } 24 protected override void OnAttached() 25 { 26 base.OnAttached(); 27 AssociatedObject.SelectionChanged += SelectionChanged; 28 } 29 protected override void OnDetaching() 30 { 31 AssociatedObject.SelectionChanged -= SelectionChanged; 32 base.OnDetaching(); 33 } 34 private void SelectionChanged(object sender, SelectionChangedEventArgs args) 35 { 36 dynamic selector = AssociatedObject; 37 SelectedItems = Enumerable.ToArray(selector.SelectedItems); 38 } 39 } 40}

補足情報

C#
WPF
Prism.Unity
Prism.Wpf
Microsoft.Xaml.Behaviors.Wpf
を使用しています。

TN8001👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

参考コードがある場合は、質問に明示してください。
(WPF) SelectedItems をViewModelで取得する - まめ - たんたんめん

以下のコード内の「SelectedStudents」にアイテム群が入らずにnullのままです。

SelectedItemsBehaviorでは、SelectedItemsIEnumerableと定義されています(実体はobject[]です)
ObservableCollection<Student>にはキャストできませんのでnullになります。

ViewModel側もそれに合わせてIEnumerableとする必要があります。

そもそもこのビヘイビアは選択が変わるたびに、SelectedItemsが丸ごと入れ替わります。
そのためObservableCollectionの意味はありません。

そしてこのコードではViewでの変更しか感知できません(TwoWay指定になっていますが^^;

xml

1<Window 2 x:Class="Questions351149.MainWindow" 3 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 4 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 5 xmlns:i="http://schemas.microsoft.com/xaml/behaviors" 6 xmlns:local="clr-namespace:Questions351149" 7 Width="800" 8 Height="450"> 9 <Window.DataContext> 10 <local:BM_StudentListViewModel /> 11 </Window.DataContext> 12 <DockPanel Margin="10"> 13 <Button 14 MinWidth="60" 15 Margin="10" 16 HorizontalAlignment="Right" 17 Command="{Binding OkButton}" 18 Content="読込" 19 DockPanel.Dock="Bottom" /> 20 21 <ListView ItemsSource="{Binding Students}" SelectionMode="Multiple"> 22 <i:Interaction.Behaviors> 23 <local:SelectedItemsBehavior SelectedItems="{Binding SelectedStudents}" /> 24 </i:Interaction.Behaviors> 25 <ListView.View> 26 <GridView> 27 <GridViewColumn DisplayMemberBinding="{Binding Id}" Header="番号" /> 28 <GridViewColumn DisplayMemberBinding="{Binding Name}" Header="氏名" /> 29 <GridViewColumn DisplayMemberBinding="{Binding Kana}" Header="フリガナ" /> 30 </GridView> 31 </ListView.View> 32 </ListView> 33 </DockPanel> 34</Window>

cs

1using Microsoft.Xaml.Behaviors; 2using Prism.Commands; 3using Prism.Mvvm; 4using System.Collections; 5using System.Collections.ObjectModel; 6using System.Diagnostics; 7using System.Linq; 8using System.Windows; 9using System.Windows.Controls; 10using System.Windows.Controls.Primitives; 11 12namespace Questions351149 13{ 14 [TypeConstraint(typeof(Selector))] 15 public class SelectedItemsBehavior : Behavior<Selector> 16 { 17 public static readonly DependencyProperty SelectedItemsProperty = 18 DependencyProperty.Register(nameof(SelectedItems), 19 typeof(IEnumerable), 20 typeof(SelectedItemsBehavior), 21 new FrameworkPropertyMetadata(null, 22 FrameworkPropertyMetadataOptions.BindsTwoWayByDefault)); 23 public IEnumerable SelectedItems 24 { 25 get => (IEnumerable)GetValue(SelectedItemsProperty); 26 set => SetValue(SelectedItemsProperty, value); 27 } 28 protected override void OnAttached() 29 { 30 base.OnAttached(); 31 AssociatedObject.SelectionChanged += SelectionChanged; 32 } 33 protected override void OnDetaching() 34 { 35 AssociatedObject.SelectionChanged -= SelectionChanged; 36 base.OnDetaching(); 37 } 38 private void SelectionChanged(object sender, SelectionChangedEventArgs args) 39 { 40 dynamic selector = AssociatedObject; 41 SelectedItems = Enumerable.ToArray(selector.SelectedItems); 42 } 43 } 44 45 public class BM_StudentListViewModel : BindableBase 46 { 47 public ObservableCollection<Student> Students { get; } 48 49 private IEnumerable _selectedStudents; 50 public IEnumerable SelectedStudents 51 { 52 get => _selectedStudents; 53 set => SetProperty(ref _selectedStudents, value); 54 } 55 56 public DelegateCommand OkButton { get; } 57 58 59 public BM_StudentListViewModel() 60 { 61 Students = new ObservableCollection<Student>(Enumerable.Range(0, 50).Select(_ => new Student())); 62 OkButton = new DelegateCommand(OkButtonExecute); 63 } 64 65 private void OkButtonExecute() 66 { 67 if (SelectedStudents == null) return; 68 foreach (Student s in SelectedStudents) 69 { 70 Debug.WriteLine(s); 71 } 72 Debug.WriteLine(""); 73 } 74 } 75 76 public class Student 77 { 78 public string Id { get; } 79 public string Name { get; } 80 public string Kana { get; } 81 82 private static int no; 83 public Student() 84 { 85 Id = $"Id{++no}"; 86 Name = $"Name{no}"; 87 Kana = $"Kana{no}"; 88 } 89 90 public override string ToString() => $"Id:{Id}, Name:{Name}, Kana:{Kana}"; 91 } 92 93 public partial class MainWindow : Window 94 { 95 public MainWindow() => InitializeComponent(); 96 } 97}

投稿2021/07/25 14:01

編集2023/07/28 14:26
TN8001

総合スコア9326

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yshr3

2021/07/25 22:46

問題を解決できました。 丁寧に解説して頂き、大変勉強になりました。 ありがとうございます。 また、以降は参考コードがある場合は、質問に明示するようにいたします。 ご指導ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問