NuGet Gallery | ReactiveProperty 2.0.0-pre4
さっきpre3リリースしましたが、バージョンアップです。
メソッド名の変更
先ほど追加したEventToReactiveCommand用のReactiveConverterとDelegateConverterクラスのConvertメソッド名をConvertToに変更しました。Convertのままだと、実装しているインターフェースのConvertメソッドとかぶってオーバーライド出来ないことがあったので…。
EventToReactiveのObsolate化
この後紹介する機能とかぶるので非推奨にしました。
EventToReactivePropertyの追加
EventToReactiveCommandのReactiveProperty版です。
以下のようなConverterを定義して。
publicclass EventToReactivePropertyViewModel { // binding from UI, event direct bindpublic ReactiveProperty<Unit> MouseDown { get; private set; } // binding from UI, event with converterpublic ReactiveProperty<Tuple<int, int>> MouseMove { get; private set; } // binding from UI, IgnoreEventArgs = truepublic ReactiveProperty<Unit> MouseEnter { get; private set; } public ReactiveProperty<string> CurrentPoint { get; private set; } public ReactiveProperty<string> Entered { get; private set; } public ReactiveProperty<string> AlertMessage { get; private set; } public EventToReactivePropertyViewModel() { // mode off RaiseLatestValueOnSubscribe, because initialValue is null.// mode off DistinctUntilChanged, because if Unit no send any values. var none = ReactivePropertyMode.None; MouseMove = new ReactiveProperty<Tuple<int, int>>(mode: none); MouseDown = new ReactiveProperty<Unit>(mode: none); MouseEnter = new ReactiveProperty<Unit>(mode: none); CurrentPoint = MouseMove .Select(p => string.Format("X:{0} Y:{1}", p.Item1, p.Item2)) .ToReactiveProperty(); Entered = MouseEnter .Select(_ => Observable.Timer(TimeSpan.Zero, TimeSpan.FromSeconds(1))) .Switch() .Select(x => "entered:" + x + "sec") .ToReactiveProperty(); this.AlertMessage = MouseDown.Select(_ => "MouseDown!").ToReactiveProperty(mode: none); } } // EventToReactiveProperty converter.// Converter/IgnoreEventArgs is useful for unit testings.// For example, MouseMovoe.Value = new Point(10, 10) is simulate MouseMove// MouseEnter.Value = new Unit() is simulate raise MouseEnter event.publicclass MouseEventToPointConverter : ReactiveConverter<dynamic, Tuple<int, int>> { protectedoverride IObservable<Tuple<int, int>> OnConvert(IObservable<dynamic> source) { return source .Select(x => x.GetPosition(null)) .Select(x => Tuple.Create((int)x.X, (int)x.Y)); } }
EventTriggerなどと組み合わせて以下のように使います。
<Grid><!-- Use Blend SDK's Interaction Trigger --><!-- Event binding to ReactiveProperty --><i:Interaction.Triggers><i:EventTrigger EventName="MouseMove"><!-- ConvertBack function is Func<object, object>--><r:EventToReactiveProperty ReactiveProperty="{Binding MouseMove}"><vm:MouseEventToPointConverter/></r:EventToReactiveProperty></i:EventTrigger><i:EventTrigger EventName="MouseDown"><!-- direct event bind --><r:EventToReactiveProperty ReactiveProperty="{Binding MouseDown}"IgnoreEventArgs="True" /></i:EventTrigger><i:EventTrigger EventName="MouseEnter"><!-- IgnoreEventArgs = true send Unit --><r:EventToReactiveProperty ReactiveProperty="{Binding MouseEnter}"IgnoreEventArgs="true" /></i:EventTrigger></i:Interaction.Triggers><TextBlock Text="{Binding CurrentPoint.Value}" /><TextBlock Text="{Binding Entered.Value}"Margin="0,100,0,0" /></Grid>