问题
I have:
public class Vm
{
private ObservableCollection<Thing> _things;
public ObservableCollection<Thing> Things
{
get { return _things ?? (_things = new ObservableCollection<Thing>()); }
}
}
And
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));
}
}
I want to observe PropertyChanges on all items in the ObservableCollection
Is rx a good fit for this?
How is the observer wired up in this case? (I could post some what-have-you-tried but I don't think it will add much)
回答1:
Rx is a perfect fit and I wouldn't call it reinventing the wheel!
Consider this simple extension method for converting property changed events to observable streams:
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);
}
}
In your view model you simply merge all individual obserable property change stream:
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; }
}
来源:https://stackoverflow.com/questions/17854345/observe-propertychanged-on-items-in-an-observablecollection-using-system-reactiv