如何使用 Reactive 绑定到 Entry 的 "focused" 事件?

How can I bind to an Entry's "focused" event with Reactive?

我正在尝试使用反应绑定到文本输入字段 "focused" 事件,但我的代码无法编译。

这是我现在正在做的,效果很好:

Entry _qty; // at class level
_qty.Focused += (s, e) => { /* do stuff */ };

尝试

但我想做这样的事情:

// class level

IObservable<string> _qtyFocusObservable;
Entry _qty;


// in a setup function

_qtyFocusObservable =
    Observable 
        .FromEventPattern<EventHandler<FocusEventArgs>>(
            x => _qty.Focused += x,
            x => _qty.Focused -= x
        );

问题

我已经尝试了上面代码的很多变体,但我收到编译器错误,指出编译器无法从 我指定的任何类型 隐式转换为 System.EventHandler<System.EventHandler<Xamarin.Forms.FocusEventArgs>>, 即使我指定的类型确实是 System.EventHandler<System.EventHandler<Xamarin.Forms.FocusEventArgs>>.

问题

如何使用反应绑定到我的 EntryFocused 事件?

因此,为了从事件中获得基本的可观察性,我通常会这样构造:

var focusObservable = Observable.FromEventPattern<EventHandler, FocusEventArgs>( x => _qty.Focused += x.Invoke, x => _qty.Focused -= x.Invoke);

然后,当我需要根据该可观察事件做某事时,我 link 对它发出如下命令:

var doStuffCommand = ReactiveCommand.CreateAsyncTask(DoStuffAsync); focusObservable.InvokeCommand(doStuffCommand);

使用类似这样的 DoStuffAsync 实现:

public async Task DoStuffAsync(object value, CancellationToken token = default(CancellationToken)) { // Do stuff here }

我对 Reactive 还是相当陌生,但这(应该?)让你朝着正确的方向前进。

干杯,编码愉快!

所以,在使用 ReactiveUI 一年之后,这就是我在聚焦输入时触发事件的方式。

var focusedObservable =
    Observable
        .FromEventPattern<FocusEventArgs>(
            x => _totalBirds.Focused += x,
            x => _totalBirds.Focused -= x)
        .Select(x => x.EventArgs.IsFocused);

    // fires when focused
    focusedObservable 
        .WhenIsTrue() // extension method, basically .Where(x => x == true)
        .ObserveOn(RxApp.MainThreadScheduler)
        .InvokeCommand(this, x => DoSomething)
        .DisposeWith(ControlBindings); // extension that uses composite disposable

    // fires when changing state back to unfocused
    focusedObservable
        .WhenIsFalse() // extension method, basically .Where(x => x == false)
        .ObserveOn(RxApp.MainThreadScheduler)
        .InvokeCommand(this, x => x.ViewModel.DoSomethingElse)
        .DisposeWith(ControlBindings); // extension that uses composite disposable

这很简单,如果您需要查看任何其他代码,请告诉我。另外,如果你想获取 .DisposeWith 扩展名,你可以获取它 here.