绑定到只读ViewModel属性并在更改时更新UI

本文关键字:更新 UI 只读 ViewModel 属性 绑定 | 更新日期: 2023-09-27 17:49:39

请参阅底部的EDIT部分…

在一个基于WPF/mvm的应用程序中,我有一个包含对象的ObservableCollection的ViewModel。这些对象中的每一个都有一个enum"Status"成员来实现INotifyPropertyChanged。

在View中,我需要显示集合中具有特定"Status"的对象的计数。由于每个对象的状态可以动态更新,因此视图需要在显示的值中反映这些动态变化。

目前,我有一个ViewModel属性,它返回每个状态的计数(每个状态一个属性)。例如:

public int TranslatedWithErrorsCount
{
    get { return FileCollection.Count(n => n.Status == TranslateStatus.TranslatedWithErrors); }
}

然而,由于每个计数属性的值只是集合当前状态的副产品(因此我从来没有设置它),我不清楚如何最好地触发事件链,从对象状态的变化开始,并以显示的计数值动态更新结束。


* EDIT *

在发布的时候,我已经有一个工作的解决方案。我不想把我已经做过的事情弄浑,因为我认为可能有更好的方法。无论如何,根据目前的反应,也许我现有的解决方案比我预期的更容易接受。

目前,我:

  1. 订阅我的集合的CollectionChanged事件,在事件处理程序中,我手动触发PropertyChanged事件对我的"计数"属性。
  2. 我基于"TrulyObservableCollection"而不是"ObservableCollection"来捕获底层对象中的单个状态更改事件。

这一切似乎都像预期的那样工作,但我认为可能有一个更干净的方法。

绑定到只读ViewModel属性并在更改时更新UI

FileCollection附加事件处理程序。CollectionChanged

在EventHandler调用RaisePropertyChanged("TranslatedWithErrorsCount")在你的ViewModel。

如果你想检查Status属性是否改变…您必须从 collectionchanged 处理程序中的项的PropertyChanged附加和分离处理程序。存储这类处理程序最简单的方法是dictionary。

编辑:实际上这是一种很好的处理方式:https://stackoverflow.com/a/8490996/1749204

您可以在ObservableCollection上连接CollectionChanged,并在其事件处理程序中连接Status的更改(可能不会编译,但您了解这个想法):

private void OnPropertyChanged(object sender, NotifyPropertyChangedEventArgs e)
{
    PropertyChanged("TranslatedWithErrorsCount");
}

FileCollection.CollectionChanged += (sender, e) => 
{
    PropertyChanged("TranslatedWithErrorsCount"); 
    if (e.NewItems != null)
    {
        foreach (var item in e.NewItems)
        {
            var inpc = item as INotifyPropertyChanged;
            inpc.PropertyChanged += OnPropertyChanged;
        }
    }
    if (e.OldItems != null)
    {
        foreach (var item in e.OldItems)
        {
            var inpc = item as INotifyPropertyChanged;
            inpc.PropertyChanged += (sender, e) => OnPropertyChanged;
        }
    }
}