如何在ViewModel中触发OnPropertyChanged更改ObservableCollection中的属性<object>?</object>

时间:2014-10-30 14:45:22

标签: .net wpf xaml

我通常不会在StackOverflow上提问,但这个问题确实在我的脑海里。

当ObservableCollection中的属性发生更改时,我需要为位于我的ViewModel中的属性触发OnPropertyChanged调用。这是我的设置:

public sealed class ObjectExtended
{
    private decimal? _percentage;
    public decimal? Percentage
    {
        get { return _percentage; }
        set
        {
            if (_percentage == value) return;
            _percentage = value;
            OnPropertyChanged("Percentage");


TODO: //Need to fire OnPropertyChanged("TotalCost") on ViewModel
        }
    }
}


public class TheViewModel : ViewModelBase
{
    private ObservableCollection<ObjectExtended> _objects;
    public ObservableCollection<ObjectExtended> Objects
    {
        get { return _objects; }
        set
        {
            if (Equals(_objects, value)) return;
            _objects = value;

            OnPropertyChanged("Objects");
        }
    }

    public decimal? TotalCost
    {
        get
        {
            var result = Objects.Where(x => x.status == SelectedObject.status).Select(x => x.costValue).Sum();
            return Math.Truncate(result * 100) / 100;
        }
    }
}

因此,在编辑百分比时,我想在视图中触发TotalCost值的更新。有关如何做到这一点的任何建议吗?

1 个答案:

答案 0 :(得分:0)

一种非常简单的方法是只需挂钩列表项的属性更改事件,并在您正在观察的属性发生更改时将您自己的属性更改。

创建可观察的集合后

Objects.CollectionChanged += Objects_CollectionChanged;

然后

void Objects_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
    {
        switch (e.Action)
        {
            case System.Collections.Specialized.NotifyCollectionChangedAction.Add:
                foreach (var item in e.NewItems.Cast<System.ComponentModel.INotifyPropertyChanged>())
                {
                    item.PropertyChanged += item_PropertyChanged;
                }
                break;
            case System.Collections.Specialized.NotifyCollectionChangedAction.Move:
                break;
            case System.Collections.Specialized.NotifyCollectionChangedAction.Remove:
                foreach (var item in e.OldItems.Cast<System.ComponentModel.INotifyPropertyChanged>())
                {
                    item.PropertyChanged -= item_PropertyChanged;
                }
                break;
            case System.Collections.Specialized.NotifyCollectionChangedAction.Replace:
                break;
            case System.Collections.Specialized.NotifyCollectionChangedAction.Reset:
                break;
            default:
                break;
        }
    }

    void item_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
    {
        if(e.PropertyName == "Percentage")
        {
            RaisePropertyChanged("TotalCost");
        }
    }

您还需要处理重置(清除)并更换箱子才能安全。

此外,如果您的可观察集合在附加集合更改处理程序之前有任何项目,那么您将不得不循环并挂钩它们。