[RxUI] 8 – 事件

[RxUI] 8 – 事件

在程序中安装适当的ReactiveUI.Events.*包。有关更多信息,请参见安装指南。可以独立使用事件包,而无需引用ReactiveUI。ReactiveUI.Events.*将始终是与ReactiveUI无关的独立包。

该包使用Pharmacist生成平台内的事件可观察值。在将来的某个时间,Pharmacist将会替代这些包。永远不要使用EventHandlers,请使用生成的Observable.FromEventPattern版本。组合多个Observable.FromEventPattern在一起可以获得惊人的合成效果。要记得使用Reactive Extensions提供的功能取消订阅

var codes = new[]
{
    Key.Up,
    Key.Up,
    Key.Down,
    Key.Down,
    Key.Left,
    Key.Right,
    Key.Left,
    Key.Right,
    Key.A,
    Key.B
};

// convert the array into an sequence
var koanmi = codes.ToObservable();

this.Events().KeyUp

    // we want the keycode
    .Select(x => x.Key)
    .Do(key => Debug.WriteLine($"{key} was pressed."))

    // get the last ten keys
    .Window(10)

    // compare to known konami code sequence
    .SelectMany(x => x.SequenceEqual(koanmi))
    .Do(isMatch => Debug.WriteLine(isMatch))

    // where we match
    .Where(x => x)
    .Do(x => Debug.WriteLine("Konami sequence"))
    .Subscribe(y => { });

在WhenActivated中使用事件

如果对视图中推送的事件作出响应并在可观察序列中引用视图模型,那么请记得取消订阅。如果视图模型的寿命超过了视图的寿命,反之亦然,则可能造成内存泄漏,而WhenActivated可以帮助避免这种情况。更多信息请,参见WhenActivated文档。

InitializeComponent();
this.WhenActivated(disposables =>
{
    RefreshButton
      // observe button click events
      // namespace: System.Windows.Controls.Primitives
      .Events().Click
      // transform arguments
      .Select(args => Unit.Default)
      // invoke command when button is clicked
      .InvokeCommand(this, x => x.ViewModel.Refresh)
      // dispose subscription when the view
      // gets deactivated.
      .DisposeWith(disposables);
});

比XAML行为更好的ReactiveUI.Events

尽管XAML行为是一种不错的技术,其允许绑定控件公开的所有事件,但其有几个缺点。首先,语法非常冗长。其次,输入事件名时会失去智能。第三,如果想修改事件模型对事件的响应方式,则需要编写新的操作和/或行为。考虑线面使用UWP XAML的示例:

<interactivity:Interaction.Behaviors>
    <core:EventTriggerBehavior EventName="Tapped">
        <core:InvokeCommandAction Command="{x:Bind ViewModel.Refresh}" />
    </core:EventTriggerBehavior>
</interactivity:Interaction.Behaviors>

使用ReactiveUI.Events,所有事件都是强类型的。这意味着IDE可以提供可用事件来帮助编程。

this.Events().Tapped
    // Use any of reactive extensions operators here!
    .Select(args => Unit.Default)
    .InvokeCommand(this, x => x.ViewModel.Refresh);

怎么将C#事件转换成Observable?

Reactive Extensions for .NET为此提供了三种方法。第一种是使用Observable.FromEventPattern

Observable.FromEventPattern<RoutedEventHandler, RoutedEventArgs>(
  handler => PasswordBox.PasswordChanged += handler,
  handler => PasswordBox.PasswordChanged -= handler) // Got IObservable here!

第二种是使用接受字符串的重载。

Observable.FromEventPattern(PasswordBox, nameof(PasswordBox.PasswordChanged))

最后一种是使用适用于所有事件委托类型的Observable.FromEvent

Observable.FromEvent<KeyPressEventHandler, KeyPressEventArgs>(
  handler => {
    KeyPressEventHandler press = (sender, e) => handler(e);
    return press;
  }, 
  handler => KeyPress += handler,
  handler => KeyPress -= handler)

有关更多信息,请参见Reactive Extensions文档

原文 https://www.reactiveui.net/docs/handbook/events

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注