Я пытаюсь добавить и удалить обработчик событий из Silverlight FrameworkElement, но я просто не могу получить корректный синтаксис.
Я хочу сделать что-то вроде этого:
let clickedEventHandler = fun args -> printfn "Click!"
fe.MouseLeftButtonDown.AddHandler( clickedEventHandler)
...
fe.MouseLeftButtonDown.RemoveHandler(clickedEventHandler)
Каков должен быть корректный способ сделать это?
, как вы уже упоминали, вам необходимо создать экземпляр делегата:
let ch = new MouseButtonEventHandler(fun obj args ->
printfn "Click!")
Тогда вы можете использовать CH
в качестве аргумента AddHandler
или Redhanlder
. Причина в том, что значение F # функции не представлено в качестве любого типа делегата. Он имеет свой собственный тип, который не является делегатом (см. Также Другим, так что обсуждение ). Вы можете увидеть разницу, если вы посмотрите на типы в F # Interactive (или против Intellisense):
> (fun (o:obj) (a:MouseButtonEventArgs) -> printfn "Click!")
val it : obj -> MouseButtonEventArgs -> unit = (...)
> new MouseButtonEventHandler(fun o a -> printfn "Click!")
val it : MouseButtonEventHandler = (...)
Что может быть запутанно, состоит в том, что f # также позволяет неявному преобразованию из значения функции лямбда в совместимый тип делегата при вызове метода, однако это Работает только тогда, когда вы даете лямбду функцию непосредственно как аргумент (я думаю):
fe.MouseLeftButtonDown.AddHandler(fun obj args ->
printfn "Click!")
Другое причина, по которой вам все еще нужно делегаты в F #, заключается в том, что делегаты имеют четко определенную семантию сравнения (они сравниваются как любые другие ссылочные типы). Для функций спецификация f # не говорит, когда они равны.
В данном случае получается, что можно сделать следующее:
let clickedEventHandler = new MouseButtonEventHandler(fun obj args -> printfn "Click!")
fe.MouseLeftButtonDown.AddHandler( clickedEventHandler)
...
fe.MouseLeftButtonDown.RemoveHandler(clickedEventHandler)