MVVM RelayCommandを経由して、リストボックスからselectedItemsのを削除
-
25-09-2019 - |
質問
私は、WPFのListBox内の項目のリストを持っています。私は、ユーザーがこれらの項目のいくつかを選択し、リストからこれらの項目を排除するために、[削除]ボタンをクリックできるようにしたい。
MVVM RelayCommandパターンを使用して、私は次のシグネチャを使用してコマンドを作成しました。
public RelayCommand<IList> RemoveTagsCommand { get; private set; }
私の見解で、私はこのように私のRemoveTagsCommandを配線します:
<DockPanel>
<Button DockPanel.Dock="Right" Command="{Binding RemoveTagsCommand}" CommandParameter="{Binding ElementName=TagList, Path=SelectedItems}">Remove tags</Button>
<ListBox x:Name="TagList" ItemsSource="{Binding Tags}" SelectionMode="Extended">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.Resources>
<DataTemplate DataType="{x:Type Model:Tag}">
...
</DataTemplate>
</ListBox.Resources>
</ListBox>
</DockPanel>
コマンドのインスタンスまで私のViewModelコンストラクタセット:
RemoveTagsCommand = new RelayCommand<IList>(RemoveTags, CanRemoveTags);
RemoveTagsの私の現在の実装では、キャストやコピーで、不格好な感じ。この?
を実装するための良い方法はあります public void RemoveTags(IList toRemove)
{
var collection = toRemove.Cast<Tag>();
List<Tag> copy = new List<Tag>(collection);
foreach (Tag tag in copy)
{
Tags.Remove(tag);
}
}
解決
私にはこのルックスかなりきれいに、あなたはSelectedItems
を使用して、VM上のプロパティにバインドMode=OneWayToSource
のことができるようにして、RemoveTags
からバインドされたコレクションのプロパティを使用するかもしれませんが。私は全くわからないんだけど、あなたがかもしれ
この場合には、厳密に型指定されたのIListコレクションを使用することができます。
他のヒント
私は例えば、モデル(ないビューモデル)内のフラグにアイテムItemContainerStyle
プロパティをバインドするListBox
にIsSelected
を使用すると思います:ます。
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="IsSelected" Value="{Binding Path=IsSelected, Mode=TwoWay}"/>
</Style>
</ListBox.ItemContainerStyle>
そして、あなたはあなたのコマンドに渡しているのか、引数を心配する必要はありません。また、私の経験でたときに、ユーザは、あなたがその情報を他の用途を見つけ、それを選択していること。
知るビューモデル内のオブジェクトのためのそれのシンプルなコマンド内のコードは次のようなものになるだろう
foreach (Tag t in Tags.Where(x => x.IsSelected).ToList())
{
Tags.Remove(t);
}
それはあなたがとにかく得ようとしているものですので、なぜあなたは、RelayCommand
するList<Tag>
の型引数を指定していませんか?実行ハンドラがTag
オブジェクトのリストで動作するようにハードコードされているので、より多くのジェネリック型を指定しても意味がありません。あなたはすでにそこに依存関係を作りましたので、あなたにも、同様、型引数にそれを作るかもしれません。次に、あなたの実行ハンドラは、任意のキャストを必要とするか、またはコピーすることはありません。
1。)バインドあなたの[削除]ボタンあなたのViewModelでのコマンド。
あなたのバインディングを設定すると、2。)、あなたのリストボックスに名前を与えるとのElementName = NameOfListBox、パス= selectedItemsの
を使用して、リストボックスからselectedItemsのを取るためにCommandParameterを使用3。)あなたのViewModelに必ずあなたのコマンドを作るには、引数に沿って通過します。あなたがIListのようにキャストできるオブジェクトを取得します。
以下は簡単な例であり、これはあなたがあなたの構造を設定役立つはずます。
ビューで
<Button Command="{Binding CommandInViewModelForRemove}"
CommandParameter="{Binding ElementName=blah,Path=SelectedItems}"
<ListBox x:Name="blah" .... />
ViewModelには、
public ViewModel(){
RemoveCommand = new RelayCommand<object>(Remove, CanRemove);
}
private void Remove(object selectedItems){
var list = (IList)selectedItems;
//do some work, cast to view models that represent list items, etc
}
希望このことができます!