Объединение событий в WPF & F # (или я схожу с ума?) - PullRequest
3 голосов
/ 26 апреля 2011

Играя с шипом, я пытаюсь перетащить ярлык WPF. Я перевел mkMouseTracker код Дона Сайма из здесь , и похоже, что он должен работать, но по какой-то причине нет никакой разницы между двумя аргументами, возвращенными из mouseEvent, поэтому моя метка никогда не перемещается .

printf ing, похоже, показывает, что параметр 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)

1 Ответ

3 голосов
/ 26 апреля 2011

Я думаю, вам нужно получить позицию события сразу после его запуска.Вполне возможно, что 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))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...