WPF PreviewMouseMoveEvent запускается медленно - PullRequest
2 голосов
/ 13 июля 2011

Я пытаюсь создать собственный элемент управления WPF, в котором применяется TranslateTransform, основанный на двух двойных значениях (TranslateX, TranslateY), которые являются данными, привязанными к TranslateTransform, это прекрасно работает при использовании кнопок или полос прокрутки для манипулирования двумя двойными значениями, но я бы хотел, чтобы пользователи перетаскивали его в пользовательский элемент управления, чтобы перевести элементы управления внутри него.

Для этого я добавил обработчик PreviewMouseDown, Up и Move в свой пользовательский элемент управления. (Насколько я понимаю, я всегда должен получать события «предварительного просмотра», потому что они туннелируют снизу вниз, а не всплывают).

//Inside the constructor of the custom control
Mouse.AddPreviewMouseDownHandler(this, new MouseButtonEventHandler(MouseDown));
Mouse.AddPreviewMouseUpHandler(this, new MouseButtonEventHandler(MouseUp));
Mouse.AddPreviewMouseMoveHandler(this, new MouseEventHandler(MouseMoved));

События обрабатываются следующими методами:

        private void OnMouseDown(object o, MouseEventArgs args)
        {
            Mouse.Capture(this, CaptureMode.Element);
            prevMousePosition = args.GetPosition(this);
        }

        private void OnMouseUp(object o, MouseEventArgs args)
        {
            Mouse.Capture(this, CaptureMode.None);
        }

        private void OnMouseMoved(object o, MouseEventArgs args)
        {
            if (args.LeftButton == MouseButtonState.Pressed)
            {
                Vector change = prevMousePosition - args.GetPosition(this);

                TranslateX += change.X;
                TranslateY += change.Y;

                prevMousePosition = args.GetPosition(this);
            }             
        }

Однако метод OnMouseMoved вызывается только тогда, когда я лихорадочно перемещаю мышь, а не если я медленно перемещаю ее (что большинство людей будет делать при перетаскивании). Также (понятно), событие полностью прекращается, когда я выхожу за пределы пользовательского элемента управления, в то время как пользователи могут продолжать перетаскивать дальше, не перемещая свою мышь.

Итак, мой вопрос: как мне зафиксировать положение мыши и события ее перемещения таким образом, чтобы пользователи могли плавно перетаскивать данные внутри пользовательского элемента управления и продолжать перетаскивание, даже если их перетаскивание заставило мышь выйти за пределы пользовательского элемента управления

(Небольшое примечание: я все еще использую .NET 3.5)

1 Ответ

1 голос
/ 13 июля 2011

После поиска "google maps, например, перетаскивание в WPF" я нашел еще один SO вопрос, который отлично ответил на мое qeuration, предоставив виртуализированный холст WPF, который может прокручиваться и масштабироваться, теперь я могу анализировать код, чтобы увидеть, как это должно быть сделано.

А пока поделюсь ссылкой: http://blogs.msdn.com/b/jgoldb/archive/2008/03/08/performant-virtualized-wpf-canvas.aspx

Виртуализированный холст WPF

Как вы, возможно, уже знаете, WPF имеет встроенную панель виртуализации VirtualizingStackPanel, которая поддерживает виртуализацию пользовательского интерфейса и размещает такие элементы, как StackPanel.

Элементы управления WPF ListBox и ListView используют эту панель по умолчанию. Другие элементы управления контейнерами, такие как Canvas, не поддерживают виртуализацию в .Net 3.0 и 3.5.

Крис Ловетт из Microsoft теперь написал отличный пример, который показывает, как вы также можете виртуализировать контейнерный элемент управления Canvas, чтобы он мог эффективно размещать и прокручивать тысячи элементов WPF, не занимая при этом большого объема памяти.

В прилагаемом загружаемом ZIP-файле есть белая бумага и код.

http://blogs.msdn.com/utility/filethumbnails/zip.gif VirtualCanvas.zip

(Извините, мне следовало искать лучше, но я не думал добавлять термины поиска аналогичного программного обеспечения, имеющего эту функцию).

...