MVVMを学習する過程で、WPFとViewModelパターンの基本的な理解を確立しました。リストを提供するときに次の抽象化を使用しており、選択した単一のアイテムに興味があります。
public ObservableCollection<OrderViewModel> Orders { get; private set; }
public ICollectionView OrdersView
{
get
{
if( _ordersView == null )
_ordersView = CollectionViewSource.GetDefaultView( Orders );
return _ordersView;
}
}
private ICollectionView _ordersView;
public OrderViewModel CurrentOrder
{
get { return OrdersView.CurrentItem as OrderViewModel; }
set { OrdersView.MoveCurrentTo( value ); }
}
次に、WPFのリストに並べ替えとフィルタリングをサポートするとともにOrdersViewをバインドできます。
<ListView ItemsSource="{Binding Path=OrdersView}"
IsSynchronizedWithCurrentItem="True">
これは、単一選択ビューに対して非常にうまく機能します。ただし、ビューでの複数選択もサポートし、選択したアイテムのリストにモデルをバインドしたいと思います。
ListView.SelectedItemsをViewModelのバッカープロパティにバインドするにはどうすればよいですか?
IsSelected
プロパティを子ViewModelに追加します(あなたの場合はOrderViewModel
):
public bool IsSelected { get; set; }
コンテナで選択したプロパティをこれにバインドします(この場合はListBoxの場合)。
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="IsSelected" Value="{Binding Mode=TwoWay, Path=IsSelected}"/>
</Style>
</ListBox.ItemContainerStyle>
IsSelected
は、コンテナの対応するフィールドに一致するように更新されます。
以下を実行することで、ビューモデルで選択した子を取得できます。
public IEnumerable<OrderViewModel> SelectedOrders
{
get { return Orders.Where(o => o.IsSelected); }
}
私はあなたを保証することができます:SelectedItems
はXAMLとして確かにバインド可能ですCommandParameter
この一般的な問題には簡単な解決策があります。動作させるには、[〜#〜] all [〜#〜]以下のルールに従う必要があります。
Ed Ballの提案 に従って、XAMLコマンドのデータバインディングで、CommandParameter
属性を定義します[〜#〜] before [〜#〜]Command
属性。 これは非常に時間のかかるバグです。
ICommand
のCanExecute
およびExecute
メソッドにobject
型のパラメーターがあることを確認してください。この方法により、データバインディングのCommandParameter
タイプがCommand
メソッドのパラメータータイプと一致しない場合に発生するsilencedキャスト例外を防ぐことができます。
private bool OnDeleteSelectedItemsCanExecute(object SelectedItems)
{
// Your code goes here
}
private bool OnDeleteSelectedItemsExecute(object SelectedItems)
{
// Your code goes here
}
たとえば、ListView
/ListBox
のSelectedItems
プロパティをICommand
メソッドまたはListView
/ListBox
自体。すごいですね。
これにより、誰かがSelectedItems
をCanExecute
パラメーターとして受け取る方法を見つけるために費やした膨大な時間を費やすことを防ぐことができます。
添付プロパティを作成してみることができます。
そうすることで、バインドするリストごとにIsSelected
プロパティを追加する必要がなくなります。私はListBox
に対してそれを行いましたが、リストビューで使用するために変更できます。
<ListBox SelectionMode="Multiple"
local:ListBoxMultipleSelection.SelectedItems="{Binding SelectedItems}" >
MVVM-LIGHTを使用している場合、次のパターンを使用できます。
https://galasoft.ch/posts/2010/05/handling-datagrid-selecteditems-in-an-mvvm-friendly-manner
特にエレガントではありませんが、少なくとも信頼できるはずです