如何将多个listview选项绑定到viewmodel?

Rub*_*ben 35 wpf mvvm selection

我正在实现listview,旁边有一个按钮.我必须能够在列表视图中选择多个项目,然后单击按钮,然后将所选项目放入列表中.但我的问题是,如何将所选项目绑定到视图模型?我将selectionmode改为多个.但是,我必须这样做:

SelectedItem={Binding path= selectedItems}
Run Code Online (Sandbox Code Playgroud)

然后在我的viewmodel中创建一个selectedItems属性,它将设置我选择的这些项目?或者这样做的正确解决方案是什么?

Jul*_*bre 39

就像Doctor已经指出的那样,你可以将SelectedItems绑定到XAML CommandParameter

经过大量的挖掘和谷歌搜索,我终于找到了解决这个常见问题的简单方法.

要使其工作,您必须遵循以下所有规则:

  1. 按照Ed Ball的建议 ',在您的XAML命令数据绑定上,定义CommandParameter属性BEFORE Command属性.这是一个非常耗时的错误.

    在此输入图像描述

  2. 确保ICommandCanExecuteExecute方法具有对象类型的参数.这样就可以防止沉默,每当发生数据绑定转换异常CommandParameter类型不匹配您的命令方法的参数类型.

    private bool OnDeleteSelectedItemsCanExecute(object SelectedItems)
    {
        // Your goes here
    }
    
    private bool OnDeleteSelectedItemsExecute(object SelectedItems)
    {
        // Your goes here
    }
    
    Run Code Online (Sandbox Code Playgroud)

例如,您可以将listview/listbox的SelectedItems属性发送给ICommand方法,也可以将listview/listbox发送给它自己.太棒了,不是吗?

希望它可以防止有人花费大量时间来弄清楚如何接收SelectedItems作为CanExecute参数.

  • IMO这篇文章应该被标记为最佳答案 - 简单并利用API.属性顺序可能很重要并不明显,这是一个很好的发现. (2认同)

Abd*_*men 23

在MVVM中执行这个多重选择有点棘手,因为SelectedItems属性不是Dependency Property.但是,您可以使用一些技巧.我发现这篇博客文章的三部曲在一些细节中描述了这个问题并提供了一些有用的解决方案.

希望这可以帮助


tec*_*ero 14

如果您已经使用System.Windows.Interactivity和Microsoft.Expression.Interactions,这里是一个没有任何其他代码/行为的解决方法.如果您需要这些,可以从这里下载

此解决方法在上面的程序集中使用了交互事件触发器和交互集属性机制.

XAML中的其他命名空间声明

xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
Run Code Online (Sandbox Code Playgroud)

XAML:

<ListView Name="MyListView" ItemsSource="{Binding ModelList}" DisplayMemberPath="Name"  Grid.Column="0">
  <i:Interaction.Triggers>
    <i:EventTrigger EventName="SelectionChanged">
      <ei:ChangePropertyAction TargetObject="{Binding Mode=OneWay}" PropertyName="SelectedItems" Value="{Binding Path=SelectedItems, ElementName=MyListView}"/>
    </i:EventTrigger>
  </i:Interaction.Triggers>
</ListView>
Run Code Online (Sandbox Code Playgroud)

查看型号:

public class ModelListViewModel
{
  public ObservableCollection<Model> ModelList { get; set; }
  public ObservableCollection<Model> SelectedModels { get; set; }

  public ModelListViewModel() {
    ModelList = new ObservableCollection<Model>();
    SelectedModels = new ObservableCollection<Model>();
  }

  public System.Collections.IList SelectedItems {
    get {
      return SelectedModels;
    }
    set {
      SelectedModels.Clear();
      foreach (Model model in value) {
        SelectedModels.Add(model);
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

在上面的示例中,只要ListView上的选择发生更改,ViewModel就会选择所选项目.

  • 此解决方案所需的软件包也可在nuget上获得:https://www.nuget.org/packages/Blend.Interctivity.WPF.v4.0/1.0.2 (2认同)

Chr*_*ian 11

你可以做的是你可以在代码隐藏中处理Button_Click(...).然后在该代码隐藏方法中,您可以通过迭代listView的所选项来创建所选项的列表.

由于允许从View访问ViewModel,因此您现在可以在ViewModel上调用方法并将所选项的列表作为参数传递.

我不确定这是否也适用于Bindings,但是使用代码隐藏也不错.

示例代码:

public void Button_Click(object sender, EventArguments arg)
{
  List<ListViewItem> mySelectedItems = new List<ListViewItem>();

  foreach(ListViewItem item in myListView.SelectedItems)
  {
    mySelectedItems.Add(item);
  }

  ViewModel.SomeMethod(mySelectedItems);
}
Run Code Online (Sandbox Code Playgroud)

编辑

这是一个极简主义的例子,XAML:

<DataTemplate
            x:Key="CarTemplate"
            DataType="{x:Type Car}">
</DataTemplate>

<ListView x:Name="myListView"
          ItemsSource="{Binding Path=Cars}"
          ItemTemplate="{StaticResource CarTemplate}">
</ListView>
Run Code Online (Sandbox Code Playgroud)

后台代码:

public void Button_Click(object sender, EventArguments arg)
    {
      List<Car> mySelectedItems = new List<Car>();

      foreach(Car item in myListView.SelectedItems)
      {
        mySelectedItems.Add(item);
      }

      ViewModel.SomeMethod(mySelectedItems);
    }
Run Code Online (Sandbox Code Playgroud)


Dum*_*y01 6

不幸的是,SelectedItems是一个只读不可绑定的属性.

我在本文中找到了很多帮助如何在WPF中将数据绑定到SelectedItems属性