2010-01-25 142 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)