0

大家好,我对 Rx 非常非常非常陌生,并试图组合一个简单的测试应用程序。它基本上使用 Rx 订阅窗口单击事件,并将文本框上的文本设置为“已单击”。这是一个 wpf 应用程序。这是xml:

<Window x:Class="Reactive.MainWindow"  
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"  
      Title="MainWindow" Height="350" Width="525">  
   <Grid>  
      <Canvas>  
        <TextBlock Name="txtClicked" Text="Rx Test"/>            
    </Canvas>  
 </Grid>  

这是背后的代码:

using System;  
using System.Linq;  
using System.Windows;  
using System.Windows.Input;  

namespace Reactive  
{
  /// <summary>  
  /// Interaction logic for MainWindow.xaml  
  /// </summary>  
public partial class MainWindow : Window  
{  
    /// <summary>  
    /// Initializes a new instance of the <see cref="MainWindow"/> class.  
    /// </summary>  
      public MainWindow()  
      {  
        InitializeComponent();  

        var xs = from evt in Observable.FromEvent<MouseEventArgs>(this, "MouseDown")
                 select evt;

        xs.ObserveOnDispatcher().Subscribe(value => txtClicked.Text = "Clicked");
    }
}
}

但由于某种原因,代码没有运行。我得到消息:

对匹配指定绑定约束的“Reactive.MainWindow”类型的构造函数的调用引发了异常。行号'3'和行位置'9

内部异常消息:

事件委托的形式必须为 void Handler(object, T) 其中 T : EventArgs。

请帮忙!!!

4

2 回答 2

4

可能为时已晚,但我建议您FromEventPattern在想要从事件中观察到的时候使用强类型方法。

IObservable<IEvent<TEventArgs>> FromEventPattern<TDelegate, TEventArgs>(
    Func<EventHandler<TEventArgs>, TDelegate> conversion,
    Action<TDelegate> addHandler,
    Action<TDelegate> removeHandler)
    where TEventArgs: EventArgs

在您的代码中,您将像这样使用它:

public partial class MainWindow : Window  
{  
    /// <summary>  
    /// Initializes a new instance of the <see cref="MainWindow"/> class.  
    /// </summary>  
    public MainWindow()  
    {  
        InitializeComponent();  

        var xs = Observable
            .FromEventPattern<MouseButtonEventHandler, MouseButtonEventArgs>(
                h => (s, ea) => h(s, ea),
                h => this.MouseDown += h,
                h => this.MouseDown -= h);

        _subscription = xs
            .ObserveOnDispatcher()
            .Subscribe(_ => txtClicked.Text = "Clicked");
    }

    private IDisposable _subscription = null;
}

此外,您应该使用订阅变量(或订阅列表)来保存调用IDisposable返回的内容Subscribe。就像在您关闭表单时删除事件处理程序一样,您也应该在完成后处理您的订阅。

于 2011-01-17T03:30:39.047 回答
2

我现在无法检查,但我相信问题是您使用了错误的EventArgs课程。Window.MouseDown事件是类型的,MouseButtonEventHandler所以你应该使用MouseButtonEventArgs

var xs = Observable.FromEvent<MouseButtonEventArgs>(this, "MouseDown");

(在这种情况下,您的查询表达式实际上并没有做任何事情 - 如果您想添加 where 子句等,您可以将其放回原处。)

于 2010-07-23T05:24:16.143 回答