2

在一個ObservableCollection項目觀察的PropertyChanged我:使用System.Reactive

public class Vm 
{ 
    private ObservableCollection<Thing> _things; 
    public ObservableCollection<Thing> Things 
    { 
     get { return _things ?? (_things = new ObservableCollection<Thing>()); } 
    } 
} 

而且

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)); 
    } 
} 

我想觀察所有項目PropertyChanges中的ObservableCollection

是一個RX很適合這個?

在這種情況下,觀察者如何接線? (我可以張貼一些你曾嘗試過的東西,但我不認爲它會增加很多)

+2

而不是重新發明輪子,你可能想看看http://www.reactiveui.net/這是做什麼和更多。 –

+0

會檢查出來,試圖學習一些rx,所以重塑不會是一場災難。去拉你的代碼並閱讀一些。 –

+0

我來這裏說的是和@JimWooley一樣的東西,即使你不使用這個庫,代碼也很乾淨,並且很容易理解爲一個工作示例。 –

回答

2

Rx是一個完美的結合,我不會說它重新發明了輪子!

考慮轉換屬性這個簡單的擴展方法變更事件來觀察的流:

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); 
    }  
} 

在您的視圖模型,你只需合併所有個人obserable屬性變換流:

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; } 
}