绑定WPF MVVM ListView内命令的MultiBinding与ViewModel属性

本文关键字:MultiBinding ViewModel 属性 命令 WPF MVVM ListView 绑定 | 更新日期: 2023-09-27 18:17:49

在我的WPF MVVM应用程序中有以下场景。有一个ListView绑定到ViewModel上的一个集合(Orders)。对于集合中的每个对象,显示关于该项的一行数据。

还有一个单元格,它本身绑定到另一个ViewModel集合(SelectedDates),它为SelectedDates集合中的每个项目创建一个复选框。

当用户单击复选框时,需要激活命令。该命令的参数必须是相应Order和SelectedDate对象的ID。

现在,我知道我可以使用MultiBinding和转换器来实现这一点。令我感兴趣的是,在研究这个问题时,人们似乎普遍认为,最好是将一个或两个参数作为ViewModel属性,并避免将它们作为参数传递。

然而,我不知道如何在这个特定的场景中(或者,实际上,在许多场景中,您正在处理绑定到ViewModel集合的ListView内部生成的命令)可以实现这一点。

所以问题是-是否有可能完全或部分使用ViewModel属性,或者在这种情况下,MultiBinding是完成工作的唯一方法?

绑定WPF MVVM ListView内命令的MultiBinding与ViewModel属性

关于MVVM的事情是,通常,我们在视图模型中有数据,所以我们不需要访问UI控件。因此,如果您将Order属性数据绑定到ListView.SelectedItem属性,那么该属性将反映所选项目…这就是如何从数据绑定的Order对象中获得Order.Id值:

int id = SelectedOrder.Id;

现在有了SelectedDates集合,我假设您也可以直接从视图模型访问它,或者通过所选的Order对象间接访问它。假设,您的Order类具有某种DateTime属性,该属性是数据绑定到从集合中选择的日期。如果是这样的话,那么您可以将INotifyPropertyChanged.PropertyChanged处理程序附加到视图模型中的Order项,该处理程序将在每次值更改时被调用:

Order类中:

public DateTime SomeProperty
{
    get { return someProperty; }
    set
    {
        someProperty = value;
        NotifyPropertyChanged("SomeProperty");
    }
}

视图模型:

public Order SelectedOrder
{
    get { return selectedOrder; }
    set
    {
        selectedOrder = value;
        NotifyPropertyChanged("SelectedOrder");
        selectedOrder.PropertyChanged += Item_PropertyChanged;
    }
}

private void Item_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
    if (e.PropertyName == "SomeProperty")
    {
        // Do something here with SelectedOrder and SelectedOrder.SomeProperty here
    }
}

如果我理解正确,那么您想要在集合中的一个项目上触发一个命令,这将导致另一个集合被更新。

实现这一目标的一种方法是为Order创建一个视图模型类(与作为视图的数据文本的viewmodel相比,有人需要为这种视图模型提出一个更好的,更少混淆的术语…),该视图模型具有IsSelected属性,您需要充当ListView项内CheckBox的绑定目标。然后,主VM维护OrderVm的集合,而不是直接维护Order。然后可以为SelectedDates集合定义getter,如下所示:

OrderVm.Where(x=>x.IsSelected)

…放弃setter,因为它实际上只是反映了其他东西的属性