大家好,我对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。
请帮助!!!
答案 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子句等,你可以把它放回去。)