How to convert a WPF Button.Click Event into Observable using Rx and F#
我正在尝试复制一些从
我想将此代码移植到F#。
这是原始的C#代码,可正确编译:
1 2 3 4 | Observable.FromEvent<RoutedEventHandler, RoutedEventArgs>( h => new RoutedEventHandler(h), h => btn.Click += h, h => btn.Click -= h)) |
这是我在F#中执行相同操作的失败尝试:
1 2 3 4 | Observable.FromEvent<RoutedEventHandler, RoutedEventArgs>( Func<EventHandler<RoutedEventArgs>, RoutedEventHandler>(fun h -> RoutedEventHandler(h)), Action<RoutedEventHandler>(fun h -> btn.Click.AddHandler h), Action<RoutedEventHandler>(fun h -> btn.Click.RemoveHandler h)) |
除了语句的第二行之外,其他所有事情都很高兴。
F#编译器抱怨
它不想将
另一方面,C#编译器似乎完全可以接受
有趣的是,在两个代码示例(C#和F#)中,
我从F#编译器收到的错误消息是:
Error 2 This expression was expected to have type obj -> RoutedEventArgs -> unit but here has type EventHandler
我在PresentationCore中找到的
如您所见,它确实将
C#编译器在幕后做一些魔术来使F#编译器没有做这项工作,或者我只是在这里遗漏了什么?
不管哪种方式,我如何在F#中使它起作用?
我知道从WPF Button.Click事件中制作
1 2 3 4 5 | open System open System.Windows.Controls let btn = new Button() let obsClick = btn.Click :> IObservable<_> |
正在检查obsClick ...
1 | val obsClick : IObservable<Windows.RoutedEventArgs> |
这是可能的,因为标准.NET事件的F#表示形式是
乔尔·穆勒(Joel Mueller)很有名,所以仅作记录:C#代码的直接翻译将是
1 2 3 4 5 | Observable.FromEvent( (fun h -> RoutedEventHandler(fun sender e -> h.Invoke(sender, e))), (fun h -> b.Click.AddHandler h), (fun h -> b.Click.RemoveHandler h) ) |