更新可观察集合中的项目时更新ViewModel

时间:2017-08-25 19:43:21

标签: c# wpf data-binding

源代码在这里: https://github.com/djangojazz/BubbleUpExample

问题是当我更新该集合中项目的属性时,我想要一个ViewModel的ObservableCollection来调用更新。我可以更新它绑定的数据,但保存集合的ViewModel不会更新,UI也不会看到它。

public int Amount
{
  get { return _amount; }
  set
  {
    _amount = value;
    if (FakeRepo.Instance != null)
    {
      //The repo updates just fine, I need to somehow bubble this up to the 
      //collection's source that an item changed on it and do the updates there.
      FakeRepo.Instance.UpdateTotals();
      OnPropertyChanged("Trans");
    }
    OnPropertyChanged(nameof(Amount));
  }
}

我基本上需要会员告诉收集的地方:“嘿我更新了你,注意并告诉父母你是其中的一员。我只是不知道冒泡的例程或回电来实现这个目的我找到的有限线程与我正在做的有点不同。我知道可以通过多种方式完成,但我没有运气。

本质上我只想看下图中的第三步,而不必先点击列。

enter image description here

2 个答案:

答案 0 :(得分:1)

如果您的基础项目遵循INotifyPropertyChanged,您可以使用一个可观察的集合,该集合将冒出属性更改通知,如下所示。

public class ItemObservableCollection<T> : ObservableCollection<T> where T : INotifyPropertyChanged
{
    public event EventHandler<ItemPropertyChangedEventArgs<T>> ItemPropertyChanged;


    protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs args)
    {
        base.OnCollectionChanged(args);
        if (args.NewItems != null)
            foreach (INotifyPropertyChanged item in args.NewItems)
                item.PropertyChanged += item_PropertyChanged;

        if (args.OldItems != null)
            foreach (INotifyPropertyChanged item in args.OldItems)
                item.PropertyChanged -= item_PropertyChanged;
    }

    private void OnItemPropertyChanged(T sender, PropertyChangedEventArgs args)
    {
        if (ItemPropertyChanged != null)
            ItemPropertyChanged(this, new ItemPropertyChangedEventArgs<T>(sender, args.PropertyName));
    }

    private void item_PropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        OnItemPropertyChanged((T)sender, e);
    } 
}

答案 1 :(得分:1)

你应该做两件事来让它发挥作用: 首先:您应该重构RunningTotal属性,以便它可以引发属性更改事件。像这样:

private int _runningTotal;
public int RunningTotal
{
    get => _runningTotal;
    set
    {
        if (value == _runningTotal)
            return;
        _runningTotal = value;
        OnPropertyChanged(nameof(RunningTotal));
    }
}

您应该做的第二件事是在UpdateTotals添加DummyTransaction后调用Trans。一个选项可能是重构AddToTrans

中的FakeRepo方法
public void AddToTrans(int id, string desc, int amount)
{            
  Trans.Add(new DummyTransaction(id, desc, amount));
  UpdateTotals();
}