9

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

4

1 回答 1

2

通过 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 类上定义的所有事件都被标记为内部的。

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

我认为也许使用 Manipulation 功能对于您正在尝试做的事情来说太过分了。可能有一种方法可以通过拖动事件和画布来实现这一点。

另外,在谷歌搜索时发现了这个,并认为它可能有一些相关性http://multitouchvista.codeplex.com/

于 2012-11-21T06:23:44.047 回答