MVVM RelayCommandを経由して、リストボックスからselectedItemsのを削除

StackOverflow https://stackoverflow.com/questions/2803672

  •  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プロパティをバインドするListBoxIsSelectedを使用すると思います:ます。

 <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
}

希望このことができます!

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top