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

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

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

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

XAML

XAML(Extensible Application Markup Language)はWPF、Silverlight、Windows PhoneそしてWindows Store appsでユーザーインターフェースを定義するために使われるXML言語です。

WPF

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

Q&A

解決済

1回答

3139閲覧

C# WPF ListBoxにおいて選択された要素だけを削除するコマンドを作りたい。

tomiieee

総合スコア27

C#

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

XAML

XAML(Extensible Application Markup Language)はWPF、Silverlight、Windows PhoneそしてWindows Store appsでユーザーインターフェースを定義するために使われるXML言語です。

WPF

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

1グッド

1クリップ

投稿2020/09/21 02:11

編集2020/09/21 02:15

前提・実現したいこと

C# WPF 初心者です。
用語の誤用/的外れな質問ありましたらご容赦ください。

リストボックスの要素の内、選択しているものだけを削除するコマンドを作りたいです。
そしてコマンドの発動条件として、リストボックス内の項目を選択していないときはボタンが押せないようにしたいです。
(リストボックスの選択モードはExtendedで行いたいです。)

リストボックスにおいて現在選択されているものを取得し、VMへ伝える方法がググっても分かりませんでした・・・
リスト用クラスにbool型のIsSelectedプロパティを用意してあるので、そちらを使った方法でも構いません。

お手数おかけしますが、ご教示よろしくお願いいたします。

該当のソースコード

XAML

1<Window x:Class="ListDelete.Views.MainWindow" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 xmlns:prism="http://prismlibrary.com/" 5 prism:ViewModelLocator.AutoWireViewModel="True" 6 Title="ListDelete" Height="350" Width="525"> 7 8 <Window.Resources> 9 <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" /> 10 </Window.Resources> 11 12 <Grid> 13 <ListBox HorizontalAlignment="Left" Height="184" Margin="42,73,0,0" VerticalAlignment="Top" Width="153" 14 ItemsSource="{Binding MyList}" 15 DisplayMemberPath="Name" 16 IsSynchronizedWithCurrentItem="True" 17 SelectionMode="Extended"> 18 19 <ListBox.ItemContainerStyle> 20 <Style TargetType="ListBoxItem"> 21 <Setter Property="IsSelected" Value="{Binding IsSelected.Value}" /> 22 </Style> 23 </ListBox.ItemContainerStyle> 24 25 </ListBox> 26 27 28 <Button Content="選択した項目を削除" HorizontalAlignment="Left" Margin="231,104,0,0" VerticalAlignment="Top" Width="127" 29 Command="{Binding Cmd_DeleteList}" /> 30 </Grid> 31</Window> 32

C#

1using Prism.Mvvm; 2using Reactive.Bindings; 3using System.Collections.ObjectModel; 4using System.Windows.Annotations; 5 6namespace ListDelete.ViewModels 7{ 8 public class MainWindowViewModel : BindableBase 9 { 10 //リスト 11 public ObservableCollection<Person> MyList { get; set; } = new ObservableCollection<Person>(); 12 13 //選択した要素を削除するコマンド 14 public ReactiveCommand Cmd_DeleteList { get; private set; } 15 16 public MainWindowViewModel() 17 { 18 //リスト生成 19 MyList.Add(new Person { Name = "AAA" }); 20 MyList.Add(new Person { Name = "BBB" }); 21 MyList.Add(new Person { Name = "CCC" }); 22 23 //コマンド発動条件設定 24 Cmd_DeleteList = 25 //ここにリストを選択していないときはボタンが押せないよう設定したい。 26 .ToReactiveCommand(); 27 28 コマンド動作定義 29 Cmd_DeleteList.Subscribe(()=> 30 { 31 //ここに選択した要素を削除するコマンドを追加したい。 32 }); 33 } 34 } 35 36 public class Person : BindableBase 37 { 38 public string Name { get; set; } 39 public ReactiveProperty<bool> IsSelected { get; set; } = new ReactiveProperty<bool>(); 40 } 41 42}

補足情報(FW/ツールのバージョンなど)

OS:win10
.NET Framework:4.7.2
Visual Studio 2019

TN8001👍を押しています

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

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

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

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

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

guest

回答1

0

ベストアンサー

ListBoxSelectedIndex等は複数選択モードだと使い物にならないのですが、選択されているかどうかの判定には使えます。

SelectedValueSelectedItemを使ってもいいです(ReactiveProperty<Person>になるだけです)

xml

1<ListBox SelectedIndex="{Binding SelectedIndex.Value}">

cs

1public class MainWindowViewModel : BindableBase 2{ 3 public ObservableCollection<Person> MyList { get; } 4 public ReactiveCommand Cmd_DeleteList { get; } 5 public ReactiveProperty<int> SelectedIndex { get; } = new ReactiveProperty<int>(); 6 7 public MainWindowViewModel() 8 { 9 MyList = new ObservableCollection<Person> 10 { 11 new Person { Name = "AAA" }, 12 new Person { Name = "BBB" }, 13 new Person { Name = "CCC" }, 14 }; 15 16 Cmd_DeleteList = 17 // SelectedIndexが-1でなければtrue 18 SelectedIndex.Select(x => x != -1) 19 // ↑の時に実行可能なコマンド作成 20 .ToReactiveCommand() 21 // ついでに購読 22 .WithSubscribe(() => 23 { 24 // 削除候補 25 var delPersons = MyList.Where(x => x.IsSelected.Value).ToArray(); 26 foreach(var person in delPersons) 27 { 28 MyList.Remove(person); 29 } 30 31 // 選択はすべて削除されたはずなので選択解除 32 SelectedIndex.Value = -1; 33 }); 34 } 35}

投稿2020/09/21 03:57

編集2023/08/12 10:03
TN8001

総合スコア9321

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

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

tomiieee

2020/09/21 05:14

問題が解決できました。 ご回答、ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問