2

我正在尝试制作一个自定义 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)

4

1 回答 1

1

在搜索“像在 WPF 中拖动一样的谷歌地图”之后,我发现了另一个 SO 问题,它通过提供可以滚动和缩放的虚拟化 WPF 画布完美地回答了我的问题,现在我可以剖析代码以了解它应该如何完成。

现在我将分享链接:http: //blogs.msdn.com/b/jgoldb/archive/2008/03/08/performant-virtualized-wpf-canvas.aspx

虚拟化 WPF 画布

您可能已经知道 WPF 有一个名为 VirtualizingStackPanel 的内置虚拟化面板,它支持 UI 虚拟化并像 StackPanel 一样布置其元素。

WPF ListBox 和 ListView 控件默认使用此面板。其他容器控件(例如 Canvas)在 .Net 3.0 和 3.5 中没有虚拟化支持。

来自 Microsoft 的 Chris Lovett 现在编写了一个很棒的示例,展示了如何虚拟化 Canvas 容器控件,以便它可以有效地托管和滚动数千个 WPF 元素,而不会消耗大量内存。

提供的可下载 ZIP 包含白皮书和代码。

虚拟画布.zip

(对不起,我应该搜索得更好,但我没有想到添加具有此功能的类似软件的搜索词)。

于 2011-07-13T09:29:23.810 回答