【问题标题】:Gain PanningMode behavior of ScrollViewer with mouse events使用鼠标事件获得 ScrollViewer 的 PanningMode 行为
【发布时间】:2012-03-17 03:20:51
【问题描述】:

我正在尝试以与在 PDF 文档中平移相同的方式平移 ScrollViewer 的内容(滚动以放大/缩小,单击 + 拖动以平移)ScrollViewer 为触摸事件内置了此功能(PanningMode),但这似乎并没有转化为 Click+Drag 事件。有没有办法告诉它/模拟这个功能?

【问题讨论】:

    标签: wpf scrollviewer panning


    【解决方案1】:

    通过 ScrollViewer 实现的四个虚拟方法在内部启用平移:

    OnManipulationCompleted
    OnManipulationDelta
    OnManipulationInertiaStarting
    and OnManipulationStarting
    

    那么这些虚方法是在哪里定义的。让我们提升层次结构。我们看到它在 OnManipulationCompletedThunk 内的 UIElement 上被调用(我确信其余的也有伴随的方法)。

    此时一切仍然是私密的,我们想要一些可以利用的东西。不幸的是,这是反射器和 ILSpy 都让我失败的地方(实际上它没有,调用站点位于我没有加载 brb 的不同 dll(PresentationCore)中)。好的回来。一旦我们查看 PresentationCore,我们有一个模糊的想法,即依赖属性是静态注册的,所以我们找到了 .cctor。这里有几行感兴趣。

    ManipulationCompletedEvent = Manipulation.ManipulationCompletedEvent.AddOwner(typeof(UIElement));

    EventManager.RegisterClassHandler(typeof(UIElement), ManipulationCompletedEvent, new EventHandler(UIElement.OnManipulationCompletedThunk));

    我们看到 OnManipulationCompletedThunk 是此类处理程序的注册回调,它侦听 ManipulationCompletedEvent。此外,ManipulationCompletedEvent 最初并未在 UIElement 上定义,它是通过 AddOwner 从 Manipulation 静态类借用的。

    搜索 Manipulation 类时,我发现它位于同一程序集中的 System.Windows.Input 命名空间中。是公开的吗,是的。凉爽的!所以此时我知道,如果我触发 ManipulationCompletedEvent 或它的任何伙伴,它最终会调用 ScrollViewer。 http://msdn.microsoft.com/en-us/library/system.windows.input.manipulation.aspx

    在这个公共静态类的文档中,我看到有很多有趣且可能有用的方法。唯一不太明显的是 AddManipulator。这东西有什么作用? Clicks.. 读取.. 哦,“每个触摸点都是一个 IManipulator 对象。例如,如果您使用两根手指调整对象的大小,则会为每个手指创建一个实现 IManipulator 的 TouchDevice。”所以 TouchDevice 是一个 IManipulator。也许这会让我对如何创建自己的操纵器有所了解。

    TouchDevice 上的属性提供了一些关于它支持的功能的线索。它有点像 MouseDevice(具有捕获、DirectlyOver 等概念),但它不支持以相同方式进行操作。相反,我们想要进行操作以响应鼠标事件。让我们更仔细地看一下 TouchDevice,看看它是如何真正实现其中一些功能的。

    TouchDevice 实现的方法有 GetPosition 和 ManipultionEnded

    GetPosition 返回 this.GetTouchPoint(relativeTo).Position; relativeTo 是一个参数

    ManipulationEnded 调用 OnManipulationEnded 转发一个名为 cancel 的 bool 参数。不确定取消是做什么的。哦,原来它没有使用,很奇怪但还可以。这基本上将捕获设置为空。 Kindof 在兔子洞的尽头,所以我们必须备份并重新评估。

    我真正想做的就是在 UIElement 上手动引发事件并查看它是否有效。 UIElement 上的 RaiseEvent 方法应该适用于此。去试试brb。 Err wait 我错过了一些东西,在 Manipulation 类上定义的所有事件都被标记为内部的。

    显然,这些事件仅供内部使用,如果不进行反思,我们就没有途径。

    我认为对于您正在尝试做的事情来说,使用“操作”功能可能有点过头了。可能有一种方法可以通过拖动事件和画布来实现这一点。

    另外,在谷歌搜索时发现了这个,并认为它可能与http://multitouchvista.codeplex.com/

    有关

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-20
      • 2013-12-28
      • 2011-02-16
      • 1970-01-01
      • 2015-02-07
      • 1970-01-01
      相关资源
      最近更新 更多