ReactivePropertyは、XAMLで使うのがしっくりきますが、Codeplex.Reactive.Extensions名前空間には、それ以外にも使える便利なメソッドが詰まってます。その中でも汎用的なINotifyPropertyChangedとINotifyCollectionChangedを監視するメソッドを紹介します。
INotifyPropertyChangedの拡張メソッド
ObservePropertyという拡張メソッドがあります。これはExpressionTreeで監視対象のプロパティを指定することで、そのプロパティを監視するIObservable>T<を作成できます。
例を以下に示します。
このようなPersonクラスがあるとして…
publicclass Person : INotifyPropertyChanged { publicevent PropertyChangedEventHandler PropertyChanged; privatevoid OnPropertyChanged([CallerMemberName]string propertyName = null) { var h = this.PropertyChanged; if (h != null) { h(this, new PropertyChangedEventArgs(propertyName)); } } privatestring name; publicstring Name { get { returnthis.name; } set { this.name = value; this.OnPropertyChanged(); } } }
Nameプロパティを監視するコードはこうなります。
var p = new Person(); p.ObserveProperty(x => x.Name) .Subscribe(x => Console.WriteLine("変更されました {0}", x)); p.Name = "tanaka"; p.Name = "kimura";
実行すると以下のようになります。
変更されました 変更されました tanaka 変更されました kimura
最初のSubscribeした時点での値がいらなかったらSkip(1)すればいいです。
INotifyCollectionChangedの拡張メソッド
INotifyCollectionChangedのを監視するのは、CollectionChangedAsObservable拡張メソッドです。
これは、CollectionChangedイベントが発行されるたびに値を通知するIObservable>NotifyCollectionChangedEventArgs<を返します。使い方は以下のようになります。
var c = new ObservableCollection<Person>(); c.CollectionChangedAsObservable() .Subscribe(x => Console.WriteLine("コレクションに変更がありました")); c.Add(new Person { Name = "tanaka" }); c.Add(new Person { Name = "kimura" });
実行するとこんな結果になります。
コレクションに変更がありました コレクションに変更がありました
ObservableCollection>T<限定になりますが、タイプセーフな監視メソッドも用意されています。
ObserveXXXXChangedメソッドでXXXXにはAddやRemoveやReplaceやMoveやResetなどがあります。これは、NotifyCollectionChangedEventArgsを用途ごとに使いやすいように加工したものになっています。
まとめ
ReactiveProperty全部つかうのが重たかったら、該当メソッドだけ切り出して使うのもありかもしれないですね。OSSですし。