2010-01-25 143 views
4

我试图添加&从Silverlight FrameworkElement中删除事件处理程序,但我无法获得正确的语法。F#:添加和删除事件处理程序

我想要做这样的事情:

let clickedEventHandler = fun args -> printfn "Click!" 
fe.MouseLeftButtonDown.AddHandler(clickedEventHandler) 
... 
fe.MouseLeftButtonDown.RemoveHandler(clickedEventHandler) 

应该是什么这样做的正确方法?

+0

如果你不担心删除处理程序,你可以使用添加。 'fe.MouseLeftButtonDown.Add(clickedEventHandler)' – gradbot 2010-01-26 17:41:38

回答

5

正如你已经提到的,你需要创建委托的实例:

let ch = new MouseButtonEventHandler(fun obj args -> 
    printfn "Click!") 

然后你可以使用ch作为参数AddHandlerRemoveHanlder。原因是,F#函数值实际上并未表示为任何委托类型。它有它自己的类型,它不是代表(另请参阅another SO discussion)。你可以看到区别,如果你看一下在F#的类型交互(或VS智能感知):

> (fun (o:obj) (a:MouseButtonEventArgs) -> printfn "Click!") 
val it : obj -> MouseButtonEventArgs -> unit = (...) 

> new MouseButtonEventHandler(fun o a -> printfn "Click!") 
val it : MouseButtonEventHandler = (...) 

什么可令人困惑的是,F#还允许从lambda表达式值隐式转换为兼容的委托类型调用时

fe.MouseLeftButtonDown.AddHandler(fun obj args -> 
    printfn "Click!")   

另一个原因,你仍然需要代表在F#是代表有一个明确的比较语义(它们分别是:法,但是这个时候你直接给lambda函数的参数(我认为)只与任何其他参考类型相比)。对于函数,F#规范并没有说明它们何时相等。

2

在这种情况下,事实证明你可以做到以下几点:

let clickedEventHandler = new MouseButtonEventHandler(fun obj args -> printfn "Click!") 
fe.MouseLeftButtonDown.AddHandler(clickedEventHandler) 
... 
fe.MouseLeftButtonDown.RemoveHandler(clickedEventHandler)