F#: добавление и удаление обработчиков событий

Я пытаюсь добавить и удалить обработчик событий из Silverlight FrameworkElement, но не могу понять правильный синтаксис.

Я хочу сделать что-то вроде этого:

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

Каким должен быть правильный способ сделать это?


person rysama    schedule 25.01.2010    source источник
comment
Если вы не беспокоитесь об удалении обработчика, вы можете использовать Add. fe.MouseLeftButtonDown.Add( clickedEventHandler )   -  person gradbot    schedule 26.01.2010


Ответы (2)


Как вы уже упоминали, вам нужно создать экземпляр делегата:

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

Затем вы можете использовать ch в качестве аргумента для AddHandler или RemoveHanlder. Причина в том, что значение функции F# на самом деле не представлено как какой-либо тип делегата. У него есть собственный тип, который не является делегатом (см. также другое обсуждение SO). Вы можете увидеть разницу, если посмотрите на типы в интерактивном F# (или VS 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# не указано, когда они равны.

person Tomas Petricek    schedule 25.01.2010

В этом случае оказывается можно сделать следующее:

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