我正在尝试理解以下代码的工作原理(取自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调用,那么我会得到相同的结果。
因此对于这一部分,我认为我的真正问题是为什么第二个事件处理程序报告不同的位置。但也许这最好作为一个单独的问题处理。
答案 0 :(得分:2)
我不确定为什么它不起作用,但你可以通过将一个闭包传递给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
参数更好。也许它会按预期工作?
答案 1 :(得分:0)
add_MouseDown
是MouseDown
活动的添加访问者的名称。
在C#中,通过编写win.MouseDown += ...
来调用此方法
在VB.Net中,通过编写AddHandler(win, AddressOf ...)
来调用它。
F#没有添加事件处理程序的特殊语法,因此您需要显式调用它。