使用鼠标事件获得ScrollViewer的PanningMode行为

时间:2012-02-27 16:36:56

标签: wpf scrollviewer panning

我试图以与在PDF文档中平移相同的方式平移ScrollViewer的内容(滚动到放大/缩小,单击+拖动以平移)ScrollViewer具有为Touch事件内置的此功能(PanningMode),但这似乎不会转换为Click + Drag事件。有没有办法告诉它/模仿这个功能?

1 个答案:

答案 0 :(得分:2)

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

OnManipulationCompleted在 OnManipulationDelta在 OnManipulationInertiaStarting在 和OnManipulationStarting

那么这些虚拟方法在哪里定义。让我们进入层次结构。我们看到它在OnManipulationCompletedThunk中被调用了UIElement(我确信其他方法也有相应的方法)。

此时一切仍然是私密的,我们希望能够利用一些东西。不幸的是,这是反射器和ILSpy都失败了我的点(实际上它没有,呼叫站点在不同的dll(PresentationCore),我没有加载brb)。好的回来。一旦我们查看了PresentationCore,我们就会有一个含糊的想法,即dependencyProperties是静态注册的,所以我们找到了.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。这件事做什么?点击..读取..哦,“每个触摸点都是一个IManipulator对象。例如,如果您使用两个手指来调整对象的大小,则会为每个手指创建一个实现IManipulator的TouchDevice。”所以TouchDevice是一个IManipulator。也许这会让我对如何创建自己的操纵器有所了解。

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

TouchDevice正在实施的方法是GetPosition和ManipultionEnded

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

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

我真正想做的就是在UIElement上手动提升事件,看看它是否有效。 UIElement上的RaiseEvent方法应该适用于此。去试试brb。错误等待我错过了一些东西,操纵类中定义的所有事件都标记为内部。

显然,这些事件仅供内部消费,如果没有做反思,我们就没有大道。

我认为使用Manipulation功能对于你想要做的事情来说是过度的。可能有一种方法可以通过拖动事件和画布来实现它。

此外,谷歌搜索时发现这一点,并认为它可能具有一定的相关性http://multitouchvista.codeplex.com/