1

INotifyPropertyChanged オブジェクトのコレクションがあり、さらに処理するためにすべての PropertyChanged イベントを単一の監視可能なシーケンスにストリーミングしたいと考えています。

ここにコードがあります

IObservable<EventPattern<PropertyChangedEventArgs>> _allEvents = null;

                // Items contains collection of item, which implements INotifyPropertyChanged
                foreach (var item in Items)
                {
                    var seq = Observable.FromEventPattern<PropertyChangedEventArgs>(item, "PropertyChanged");

                    if (_allEvents == null)
                        _allEvents = seq;
                    else
                        _allEvents.Merge(seq);
                }

                // subscribe to the aggregated observable sequence
                if (_allEvents != null)
                    _allEvents.Subscribe(evt => Trace.WriteLine(" Property Changed -> " + evt.EventArgs.PropertyName));

単一のサブスクライブは、集計されたシーケンスで何らかの理由でここでは機能しません。(Reactive Extensions の Merge 関数を使用して) 誤って集計したようです。ただし、ループ内のサブスクライブは完全に機能します。

多くのイベント ストリームをリアクティブな拡張機能を使用して 1 つに集約する方法を教えてください。

ありがとう

4

1 に答える 1

1

これを試して:

var _allEvents = Observable
   .Merge(Items
       .Select(item => Observable
           .FromEventPattern<PropertyChangedEventArgs>(item, "PropertyChanged")));

_allEvents.Subscribe(evt => Trace.WriteLine(" Property Changed -> " + evt.EventArgs.PropertyName));

あなたのアプローチがうまくいかない理由は、あなたがIObservable<T> Observable.Merge<T>(this IObservable<T> first, IObservable<T> second). this の戻り値の型は結果のオブザーバブルです。Merge が Observable を変更したと考えていたかもしれませんが、Observable は (一種の) 不変であると考えることができます。アプローチを機能させる方法は次のとおりです。

_allEvents = _allEvents.Merge(seq);

しかし... うん。そうしないでください。

于 2012-02-21T21:41:07.100 に答える