C# 使用System.Reactive观察ObservableCollection中项目的属性更改

C# 使用System.Reactive观察ObservableCollection中项目的属性更改,c#,observablecollection,system.reactive,inotifypropertychanged,C#,Observablecollection,System.reactive,Inotifypropertychanged,我有: 我想观察ObservableCollection中所有项目的属性更改 rx适合这个吗 在这种情况下,观察者是如何连接的?(我可以发布一些你尝试过的东西,但我不认为它会增加太多)Rx是一个完美的选择,我不会把它称为重新发明轮子 考虑将属性更改事件转换为可观察流的简单扩展方法: public class Thing :INotifyPropertyChanged { private string _value; public string Value {

我有:

我想观察ObservableCollection中所有项目的属性更改

rx适合这个吗


在这种情况下,观察者是如何连接的?(我可以发布一些你尝试过的东西,但我不认为它会增加太多)

Rx是一个完美的选择,我不会把它称为重新发明轮子

考虑将属性更改事件转换为可观察流的简单扩展方法:

public class Thing :INotifyPropertyChanged
{
    private string _value;
    public string Value
    {
        get { return _value; }
        set
        {
            if (value == _value) return;
            _value = value;
            OnPropertyChanged();
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    [NotifyPropertyChangedInvocator]
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }
}
公共静态类notifyPropertyChangedExtrade
{
公共静态IObservable When nPropertyChanged(此NotifyPropertyChanged NotifyPropertyChanged)
{
返回可观察的.FromEvent(
ev=>notifyPropertyChanged.PropertyChanged+=ev,
ev=>notifyPropertyChanged.PropertyChanged-=ev);
}    
}
在视图模型中,您只需合并所有单独的可观测属性更改流:

public static class NotifyPropertyChangedExtensions
{
  public static IObservable<PropertyChangedEventArgs> WhenPropertyChanged(this NotifyPropertyChanged notifyPropertyChanged)
  {
      return Observable.FromEvent<PropertyChangedEventHandler, PropertyChangedEventArgs>(
        ev => notifyPropertyChanged.PropertyChanged += ev, 
        ev => notifyPropertyChanged.PropertyChanged -= ev);
  }    
}
公共类虚拟机
{
只读串行订阅;
公共虚拟机()
{
订阅=新的SerialDisposable();
事物=新的可观察集合();
Things.CollectionChanged+=ThingsCollectionChanged;
}
void ThingsCollectionChanged(对象发送方,NotifyCollectionChangedEventArgs e)
{
订阅。一次性=
Things.Select(t=>t.WhenPropertyChanged())
.Merge()
.认购(在已变更的物业上);
}
已更改PropertyChanged(PropertyChangedEventArgs对象)上的无效
{
//托多!
}
公共可观测集合事物{get;private set;}
}

与其重新发明轮子,不如看看是哪一个做了这件事,还有更多。我会看看,尝试学习一些rx,这样重新发明就不会是一场灾难。我来这里跟@JimWooley说同样的话,即使你不使用这个库,作为一个工作示例,代码也是非常干净和容易理解的。rx不是一个很好的例子吗?这真的取决于你想要实现什么,以及你需要做多少流的协调。在某些情况下,简单的事件处理程序就可以了。Rx有利于更复杂的协调,尽管有人说所有事件都应该被重新描述为可观测的,这可能有点过火了。FWIW,ReactiveUI是一个在内部使用Rx的MVVM框架。
public static class NotifyPropertyChangedExtensions
{
  public static IObservable<PropertyChangedEventArgs> WhenPropertyChanged(this NotifyPropertyChanged notifyPropertyChanged)
  {
      return Observable.FromEvent<PropertyChangedEventHandler, PropertyChangedEventArgs>(
        ev => notifyPropertyChanged.PropertyChanged += ev, 
        ev => notifyPropertyChanged.PropertyChanged -= ev);
  }    
}
public class VM
{
  readonly SerialDisposable subscription;

  public VM()
  {
    subscription = new SerialDisposable();
    Things = new ObservableCollection<Thing>();
    Things.CollectionChanged += ThingsCollectionChanged;
  }

  void ThingsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
  {
    subscription.Disposable = 
      Things.Select(t => t.WhenPropertyChanged())
            .Merge()
            .Subscribe(OnThingPropertyChanged);
  }

  void OnThingPropertyChanged(PropertyChangedEventArgs obj)
  {
    //ToDo!
  }

  public ObservableCollection<Thing> Things { get; private set; }
}