【发布时间】:2012-09-15 06:37:32
【问题描述】:
我试图了解为什么以下代码有效(取自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))
这会弹出两个消息窗口,第一个显示窗口内的正确位置,第二个显示另一个愚蠢的位置。但如果我真的将 add_MouseDown 调用替换为 addHandler 调用,那么我会得到相同的结果。
所以对于这一部分,我认为我真正的问题是为什么第二个事件处理程序报告不同的位置。但也许这最好作为一个单独的问题来处理。
【问题讨论】:
-
添加类型注解是否有效:(
sender: obj)?事实上,函数是泛型的,与MouseButtonEventHandler的类型不匹配。 -
您的代码有一些问题:(1)
string.Format无法在 F# 中编译 (2) 您没有使用sender(除了将其存储在win中) . -
@Daniel (1) 哎呀,我在我的代码中更改了它,但在创建问题时直接从网站复制,只是在上面更改它 (2) 不正确,win 传递给 GetPosition跨度>