2012-05-18 46 views
2

WPF控件具有許多具有相同名稱但不共享相同接口或基類的事件成員。 F#的類型約束支持寫函數,該函數在所有具有相同成員的對象上工作。 然後,如果我可以爲一個事件成員編寫類型約束,我可以用許多控件的相同方式編寫curried函數來促進屬性設置。如何爲事件成員編寫類型約束?

open System.Windows.Controls 
let inline click handler control = 
    (^T:(member Click:IEvent<_,_>)control) 
    .Add handler 

Button() 
|> click (fun _ ->()) // error! 

MenuItem() 
|> click (fun _ ->()) // error! 

type A() = 
    [<CLIEvent>] 
    member __.Click = Event<_>().Publish 
A() |> click (fun _ ->()) // It works! but IntelliSense shows the member as "event A.Click .." 

但上面的代碼不工作.. 我猜寫類型約束爲事件成員是不可能的.. 因爲它是一個小問題,如果我們的語言功能解決每一個小問題, 語言會變得如此複雜,因爲沒有人可以使用! (現在F#似乎強大而簡單)

然後我想知道一些替代方法來解決這個問題,如果它存在。

+0

這是最好的,如果你發佈你的答案,你可以接受你自己的答案。 –

+0

我必須等待8小時才能回答我自己的問題。一小時後我會回答。謝謝! – nagat01

回答

1

我發表這個問題後自己解決了。您可以通過調用方法add_ *和remove_ *來訪問事件成員。類型約束與方法調用一起使用。謝謝!

let inline click handler control = 
    let handler = RoutedEventHandler(fun _ e -> handler e) 
    (^T:(member add_Click:RoutedEventHandler->unit)control,handler) 

Button() |> click (fun _ ->()) // works! 
MenuItem() |> click (fun _ ->()) // works!