Получите поведение PanningMode ScrollViewer с событиями мыши

Я пытаюсь перемещаться по содержимому ScrollViewer так же, как вы перемещаетесь по документу PDF (прокручивайте, чтобы увеличить/уменьшать масштаб, щелкните + перетащите, чтобы панорамировать). В ScrollViewer встроена эта функция для событий касания (PanningMode) , однако это не похоже на события Click+Drag. Есть ли способ сказать/эмулировать эту функциональность?


person Ben K.    schedule 27.02.2012    source источник


Ответы (1)


Панорамирование обеспечивается четырьмя виртуальными методами, реализованными в ScrollViewer:

OnManipulationCompleted
OnManipulationDelta
OnManipulationInertiaStarting
and OnManipulationStarting

Так где же определены эти виртуальные методы. Поднимемся по иерархии. Мы видим, что он вызывается в UIElement внутри OnManipulationCompletedThunk (я уверен, что для остальных тоже есть сопутствующие методы).

На данный момент все по-прежнему конфиденциально, мы хотим что-то использовать. К сожалению, это тот момент, когда меня подвели и рефлектор, и ILSpy (на самом деле это не так, сайт вызова находится в другой dll (PresentationCore), которую я не загрузил brb). Хорошо назад. Как только мы заглянем в PresentationCore, у нас появится смутное представление о том, что dependencyProperties регистрируются статически, поэтому мы находим файл .cctor. Здесь есть пара интересных строк.

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

а также

EventManager.RegisterClassHandler (typeof (UIElement), ManipulationCompletedEvent, новый EventHandler (UIElement.OnManipulationCompletedThunk));

Мы видим, что OnManipulationCompletedThunk является зарегистрированным обратным вызовом для этого обработчика класса, который прослушивает ManipulationCompletedEvent. Кроме того, ManipulationCompletedEvent изначально не определен в UIElement, он заимствован из статического класса Manipulation через AddOwner.

Выполняя поиск класса Manipulation, я вижу, что он находится в пространстве имен System.Windows.Input в той же сборке. Это публично, да. Прохладный! так что на данный момент я знаю, что если я запущу ManipulationCompletedEvent или любого из его приятелей, он в конечном итоге вызовет ScrollViewer. http://msdn.microsoft.com/en-us/library/system.windows.input.manipulation.aspx

В документации к этому общедоступному статическому классу я вижу кучу интересных и, возможно, полезных методов. Единственное, что неочевидно, это AddManipulator. Что эта штука делает? Щелчки… читаются… о, «Каждая точка касания — это объект IManipulator. Например, если вы используете два пальца для изменения размера объекта, для каждого пальца создается TouchDevice, реализующий IManipulator». Итак, TouchDevice — это IManipulator. Может быть, это даст мне некоторое представление о том, как создать свой собственный манипулятор.

Свойства на TouchDevice дают некоторое представление о функциях, которые он поддерживает. Это похоже на MouseDevice (имеет концепцию захвата, DirectlyOver и т. д.), но не поддерживает манипуляции таким же образом. Скорее мы хотим выполнять манипуляции в ответ на события мыши. Давайте внимательно посмотрим на TouchDevice, чтобы увидеть, как он на самом деле реализует некоторые из этих функций.

TouchDevice реализует следующие методы: GetPosition и ManipultionEnded.

GetPosition возвращает this.GetTouchPoint(relativeTo).Position; относительное — это параметр

ManipulationEnded вызывает OnManipulationEnded, пересылая логический параметр с именем cancel. Не уверен, что отмена делает еще. о, оказывается, он не используется, странно, но ладно. Это в основном устанавливает для захвата значение null. Вид в конце кроличьей норы здесь, так что нам придется сделать резервную копию и переоценить.

Все, что я действительно хочу сделать, это вручную вызвать события в UIElement и посмотреть, работает ли это. Для этого должен работать метод RaiseEvent в UIElement. собираюсь попробовать брб. Э-э, подождите, я что-то пропустил, все события, определенные в классе Manipulation, помечены как внутренние.

Ясно, что эти события предназначены только для внутреннего потребления, и, если не размышлять, у нас нет пути туда.

Я думаю, что, возможно, использование функции «Манипуляция» является излишним для того, что вы пытаетесь сделать. Вероятно, есть способ реализовать это с помощью простого события перетаскивания и холста.

Кроме того, нашел это во время поиска в Google и подумал, что это может иметь некоторое значение http://multitouchvista.codeplex.com/

person user1834059    schedule 21.11.2012