質問
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
この一般的な問題には簡単な解決策があります。動作させるには、すべて次のルールに従う必要があります:
-
Ed Ballの提案に従って、XAMLコマンドのデータバインディングで、
CommandParameter
属性 BEFORECommand
属性。 これは非常に時間がかかるバグです。 -
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}" >
詳細: WPF&#8211; ListBox SelectedItemsのバインド&#8211;添付プロパティVSスタイル。
MVVM-LIGHTを使用している場合、次のパターンを使用できます。
https:// galasoft .ch / posts / 2010/05 / handling-datagrid-selecteditems-in-an-mvvm-friendly-manner
特にエレガントではありませんが、少なくとも信頼できるはずです