在Windows Phone 8中使用按钮点击并按住事件的Rx

时间:2014-09-16 07:46:41

标签: c# windows-phone-8 system.reactive

我有一个简单的Windows Phone 8应用程序,带有按钮和文本框。如何使用Reactive Extensions按钮点击并按住事件来更改TextBox文本?

void AttachRx()
    {
IScheduler cs = new DispatcherScheduler(Deployment.Current.Dispatcher);

        Observable.FromEvent<System.Windows.Input.KeyEventArgs>(btn, "Tap").Throttle(TimeSpan.FromSeconds(.5), cs)
            .Do(a => ChangeText()).Subscribe();
    }

错误消息:

  

{System.InvalidOperationException:事件委托的格式必须为void Handler(object,T),其中T:EventArgs。      at Microsoft.Phone.Reactive.Observable.FromEvent [TEventArgs](Object target,String eventName)      在PhoneApp4.MainPage.AttachRx()      在PhoneApp4.MainPage..ctor()}

1 个答案:

答案 0 :(得分:1)

这里有几个问题要解决。

您报告的错误明确指出您尝试添加到Tap事件的代理不兼容 - 这是有道理的,因为我不认为Tap事件有{{1}有效载荷(我认为它是KeyEventArgs)?你也可能最好使用我在下面的例子中使用的GestureEventArgs。这可以更容易,因为你可以推断出Observable.FromEventPattern类型。

警告 - 由于目前我的笔记本电脑上只有WP8.1 SDK,因此我只有Win EventArgs事件与Tapped不同,所以我刚刚阅读了Tap上的文档而没有运行下面的示例。

假设名为Tap的{​​{1}}和名为txt的Button以及要设置文本的函数btn,请执行以下操作:

TextBox

请注意以下几点:

  • 当标准.NET事件可用时使用string GetText() - 它比Observable.FromEventPattern<GestureEventArgs>(btn, "Tap") .Throttle(TimeSpan.FromSeconds(0.5)) .Select(_ => GetText()) .ObserveOnDispatcher() .Subscribe(x => this.txt.Text = x); 更适合这种情况,而FromEventPattern确实存在以处理不合规代表。
  • 不要像这样使用FromEvent。它起到副作用的作用,并不是真正的惯用功能反应式编程。这样做通常也可能导致更复杂的查询出现意外问题。而是使用Do将输入事件投影到所需的结果。
  • 不要在调度程序上运行Select - 使用默认调度程序(或使用Throttle参数化可测试性。您不需要在调度程序上运行Throttle - 它最好在您只想在准备好更新UI​​时转移到调度程序。
  • 如果您导入nuget包.Throttle(TimeSpan.FromSeconds(0.5), Scheduler.Default),则可以使用rx-xaml来获取当前的调度程序。虽然为了可测试性,您可能希望使用ObservableOnDispatcher(也在rx-xaml中)的重载,该重载采用依赖对象,例如您正在运行的页面 - 例如ObserveOn如果您在页面代码隐藏中设置订阅,例如页面本身就可以。

上面的示例假设ObserveOn(this)是同步的。如果您需要进行异步调用以获取要显示的文本,请使用以下模式(假设GetText具有GetText返回类型):

Task<String>

请注意Observable.FromEventPattern<GestureEventArgs>(btn, "Tap") .Throttle(TimeSpan.FromSeconds(0.5), Scheduler.Default) .Select(_ => Observable.FromAsync(GetText) .ObserveOn(this)) .Switch() .Subscribe(x => this.Name.Text = x); ObserveOn的奇怪展示位置。简单解释这个原因是非常复杂的(我不确定它与这个问题有多相关),但基本上它避免了竞争条件,如果对早期事件的长时间运行异步GetText调用可能会覆盖由于后来的事件导致短暂的通话结果。