玩穗,我正试图拖动WPF标签。我从here翻译了Don Syme的mkMouseTracker
代码,它看起来应该有效,但出于某种原因,从mouseEvent
返回的两个args之间从来没有任何区别,所以我的标签从不动。
printf
似乎表明last
参数被moveArgs中的值吞噬/替换。这与使用ref
吗?
对不起,代码块有点长,但它是自包含的。
#r "WindowsBase"
#r "PresentationCore"
#r "PresentationFramework"
#r "System.Xaml"
open System
open System.Windows
open System.Windows.Media
open System.Windows.Controls
let window = new Window(Name="Test",Width=500.0,Height=500.0)
window.Visibility <- Visibility.Visible
window.Show()
let l = new System.Windows.Controls.Label(Height = 30., Width = 150.,
BorderBrush = Brushes.Black, BorderThickness = Thickness(3.))
window.Content <- l
let mkMouseTracker (c : #UIElement) =
let event = new Event<_>()
let lastArgs = ref None
c.MouseDown.Add(fun args -> lastArgs := Some (args :> Input.MouseEventArgs ))
c.MouseUp .Add(fun args -> lastArgs := None)
c.MouseMove.Add(fun moveArgs ->
match !lastArgs with
| Some last -> event.Trigger(last,moveArgs); lastArgs := Some moveArgs
| None -> ())
event.Publish
let mouseEvent = mkMouseTracker l
mouseEvent.Add(fun (args1, args2) ->
let pos1, pos2 = args1.GetPosition(l), args2.GetPosition(l)
l.RenderTransform <- TranslateTransform(pos2.X - pos1.X, pos2.Y - pos1.Y)
l.Content <- sprintf "%A: %A -> %A" args1.Timestamp pos1 pos2)
答案 0 :(得分:3)
我认为您需要在事件触发后立即获取事件的位置。很可能WPF正在为所有事件(或类似事件)重用可变MouseEventArgs
对象,因此稍后调用GetPosition
会给你相同的点。
以下代码执行某事。它不能完全运行 - 标签被移动到错误的位置,所以它仍然需要修复,但它应该让你开始: - )。
let mkMouseTracker (e : #UIElement) =
let event = new Event<_>()
let lastArgs = ref None
e.MouseDown.Add(fun args -> lastArgs := Some(args.GetPosition(e)))
e.MouseUp .Add(fun args -> lastArgs := None)
e.MouseMove.Add(fun moveArgs ->
match !lastArgs with
| Some last ->
let pos = moveArgs.GetPosition(e)
event.Trigger(last,pos)
lastArgs := Some pos
| None -> ())
event.Publish
let mouseEvent = mkMouseTracker l
mouseEvent.Add(fun (pos1, pos2) ->
l.RenderTransform <- TranslateTransform(pos2.X - pos1.X, pos2.Y - pos1.Y)
l.Content <- sprintf "%A" (pos2.X - pos1.X, pos2.Y - pos1.Y))