迫切需要Rx.Net的帮助

时间:2010-07-23 05:03:59

标签: c# wpf system.reactive

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

<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

InnnerException消息:

  

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

请帮助!!!

2 个答案:

答案 0 :(得分: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。就像在关闭表单时删除事件处理程序一样,您也应该在完成后处理订阅。

答案 1 :(得分:2)

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

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

(在这种情况下,你的查询表达式并没有真正做任何事情 - 如果你想添加where子句等,你可以把它放回去。)