使用MVVM管理多个选择

时间:2009-04-29 16:35:11

标签: c# .net data-binding mvvm

在我学习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 ); } 
}

然后我可以将OrdersView与支持排序和过滤绑定到WPF中的列表:

<ListView ItemsSource="{Binding Path=OrdersView}" 
          IsSynchronizedWithCurrentItem="True">

这对单选视图非常有效。但我还想支持视图中的多个选择,并让模型绑定到所选项的列表。

如何将ListView.SelectedItems绑定到ViewModel上的backer属性?

4 个答案:

答案 0 :(得分:94)

IsSelected属性添加到您的子ViewModel(在您的情况下为OrderViewModel):

public bool IsSelected { get; set; }

将容器上的selected属性绑定到此(在本例中为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); }
}

答案 1 :(得分:12)

我可以向您保证:SelectedItems确实可绑定为XAML CommandParameter

这个常见问题有一个简单的解决方案;要使其发挥作用,您必须遵循所有以下规则:

  1. 关注Ed Ball's suggestion,在您的XAML命令数据绑定中,定义CommandParameter属性 BEFORE Command属性。 这是一个非常耗时的错误

    enter image description here

  2. 确保您的ICommand CanExecuteExecute方法的参数类型为object。这样,只要数据绑定的CommandParameter类型与您的Command方法的参数类型不匹配,就可以阻止沉默强制转换异常:

    private bool OnDeleteSelectedItemsCanExecute(object SelectedItems)  
    {
         // Your code goes here
    }
    
    private bool OnDeleteSelectedItemsExecute(object SelectedItems)  
    {
        // Your code goes here
    }
    
  3. 例如,您可以向ListView方法或ListBox / {发送SelectedItems / ICommand ListView媒体资源{1}}本身。太好了,不是吗?

    我希望这可以防止有人花费大量时间来确定如何将ListBox作为SelectedItems参数接收。

答案 2 :(得分:4)

可以尝试创建附加属性。

这样做可以为您绑定的每个列表添加IsSelected属性。我已经为ListBox完成了它,但可以修改它以在列表视图中使用a。

<ListBox SelectionMode="Multiple"
         local:ListBoxMultipleSelection.SelectedItems="{Binding SelectedItems}" >

更多信息:WPF – Binding ListBox SelectedItems – Attached Property VS Style

答案 3 :(得分:1)

如果你正在使用MVVM-LIGHT,你可以使用这种模式:

https://galasoft.ch/posts/2010/05/handling-datagrid-selecteditems-in-an-mvvm-friendly-manner

不是特别优雅,但看起来至少应该是可靠的