我试图了解为什么以下代码有效(取自http://jyliao.blogspot.com/2007/10/learning-wpf.html):

open System
open System.Windows
open System.Windows.Input

(* From Chap 1 - HandleAnEvent.cs *)
let WindowOnMouseDown sender (args:MouseButtonEventArgs) =
   let win = unbox<Window> sender
   let str = sprintf "Window clicked with %A button at point (%A)" args.ChangedButton (args.GetPosition win)
   MessageBox.Show(str)|>ignore

let win = new Window()
win.Title <- "Handle an Event"
win.add_MouseDown(new MouseButtonEventHandler(WindowOnMouseDown))

#if COMPILED
[<STAThread()>]
do
    let app =  new Application() in
    app.Run(win) |> ignore
#endif


我不理解的部分是对add_MouseDown的调用。当我将鼠标悬停在VS中的调用上时,它告诉我该方法来自UIElement类,但在.NET类库中找不到对该方法的任何引用。

在F#中,我希望该调用为:

win.MouseDown.AddHandler (new MouseButtonEventHandler(WindowOnMouseDown))


当我进行此更改时,弹出的消息框不再显示您单击的窗口内的坐标。取而代之的是,它显示的坐标与鼠标在窗口中的单击位置无关,但是随着您在屏幕上四处移动窗口而改变。因此,似乎sender参数引用的是窗口以外的某些UI元素。

有谁知道为什么使用add_MouseDown可以工作(以及在哪里记录了此方法的存在),以及为什么不使用AddHandler呢?

我正在使用VS2010,F#2.0,.NET 3.0库。

更新:

啊,我只是意识到使用AddHandler与使用add_MouseDown的工作方式不同是错误的。我实际上一直在做的是使用两种不同的方法一个接一个地添加两个事件处理程序:

win.add_MouseDown(new MouseButtonEventHandler(WindowOnMouseDown))
win.MouseDown.AddHandler (new MouseButtonEventHandler(WindowOnMouseDown))


这会弹出两个消息窗口,第一个显示窗口内的正确位置,第二个显示此其他愚蠢的位置。但是,如果我用addHandler调用真正替换了add_MouseDown调用,那么我会得到相同的结果。

所以对于这部分,我认为我真正的问题是为什么第二个事件处理程序报告一个不同的位置。但这也许最好作为一个单独的问题来处理。

最佳答案

我不确定为什么它不起作用,但是您可以通过将闭包传递给Add来完成相同的操作:

let win = Window()
win.MouseDown.Add(fun args ->
  let str = sprintf "Window clicked with %O button at point (%O)" args.ChangedButton (args.GetPosition(win))
  MessageBox.Show(str) |> ignore)


现在,很清楚win指的是什么(无需拆箱)。无论如何,这比无类型的sender参数要好。也许会按预期工作?

关于wpf - UIElement.add_MouseDown哪里来自f#?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/12432595/

10-09 02:45