【问题标题】:MVVM - binding to aggregated propertyMVVM - 绑定到聚合属性
【发布时间】:2018-02-22 15:05:07
【问题描述】:

我有以下视图模型:

public class ViewModel: INotifyPropertyChanged
{
    public ObservableCollection<Item> Items { get; set; }
    ...
}
public class Item: INotifyPropertyChanged
{
    public SubItem A { get; set; }
    public SubItem B { get; set; }
    ...
}
public class SubItem: INotifyPropertyChanged
{
    public bool Valid { get; set; }
    ...
}

xaml:

<ListBox ItemsSource="{Binding Items}" ..>

如果我想显示文本"Valid item",如果A.ValidB.Valid 都是true,那么:

  1. 我可以通过在视图中添加逻辑(项目数据模板)来做到这一点,例如使用可见性和额外的容器:

    <Grid Visibility="{Binding A.Valid}" Converter=...>
        <TextBlock Text="Valid item" Visibility="{Binding B.Valid}" Converter=... \>
    </Grid>
    
  2. 或者我可以向项目视图模型添加一个新属性:

    public class Item: INotifyPropertyChanged
    {
        public bool Valid => A.Valid && B.Valid; // bind to this
        ...
    }
    

    问题是SubItem 的任何一个通知都不会更新视图。

在 (1) 的情况下,绑定将订阅 PropertyChanged 事件:Item 和相应的 SubItem。在 (2) 的情况下,绑定只知道 Item.Valid 属性,所以我必须这样做:

public class Item: INotifyPropertyChanged
{
    SubItem _a;
    public SubItem A
    {
        get { return _a; }
        set
        {
            _a.PropertyChanged -= bla;
            _a = value;
            _a.PropertyChanged += bla;
            OnPropertyChanged(nameof(A));
            OnPropertyChanged(nameof(Valid));
        }
    }
    void bla(object sender, PropertyChangedEventArgs e) =>
        OnPropertyChanged(nameof(Valid));
    ...
}

这太糟糕了。所以我更喜欢(1)(有时使用数据触发器,但这无关紧要)。

是否有其他选项可以实际拥有 viewmodel 属性 (2) 但没有麻烦?

【问题讨论】:

    标签: c# wpf mvvm propertychanged


    【解决方案1】:

    在这种特殊情况下,数据绑定方法似乎最简单。这样,您就可以依赖 WPF 的数据绑定机制为您处理事件订阅,而不必通过代码手动完成。

    我知道的唯一其他处理方法是使用某种中介对象。当SubItemValid 属性发生更改时,您会发送一条消息,表明这已发生。您的 Item 类(已订阅此消息)通过检查 AB 的当前有效状态来处理它,然后相应地设置自己的 Valid 属性。

    然而,这种方法并非没有问题。一方面,您需要将中介对象注入到您的 ViewModel 对象中。此外,您的 Item 对象需要在适当的时间订阅和取消订阅相关消息(通常在对象创建和销毁时)。所有这些管道虽然仍然比直接处理属性更改事件更容易,但比仅使用数据触发器和依赖 WPF 的绑定机制 IMO 更困难。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-04-19
      • 2011-05-20
      • 2014-09-29
      • 2011-08-23
      • 1970-01-01
      • 2011-08-26
      • 2010-12-20
      • 2020-04-01
      相关资源
      最近更新 更多