C# 使用System.Reactive观察ObservableCollection中项目的属性更改
我有: 我想观察ObservableCollection中所有项目的属性更改 rx适合这个吗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 {
在这种情况下,观察者是如何连接的?(我可以发布一些你尝试过的东西,但我不认为它会增加太多)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; }
}