2012-02-27 9 views
8

Estoy intentando desplazarme por el contenido de un ScrollViewer de la misma forma que lo haría en un documento PDF (desplazarse para acercar/alejar, hacer clic + arrastrar para desplazar) ScrollViewer tiene esta funcionalidad incorporada para Touch events (PanningMode), sin embargo, esto no parece traducirse en Click + Drag events. ¿Hay alguna manera de decirle/emular esta funcionalidad?Comportamiento de Gain PanningMode de ScrollViewer con eventos de mouse

Respuesta

2

toma panorámica está activado internamente por cuatro métodos virtuales implementadas por ScrollViewer:

OnManipulationCompleted OnManipulationDelta OnManipulationInertiaStarting y OnManipulationStarting

Entonces, ¿dónde están estos métodos virtuales definidos. Vamos a subir la jerarquía. Vemos que se llama a UIElement dentro de OnManipulationCompletedThunk (estoy seguro de que hay métodos concomitantes para el resto también).

Todo sigue siendo privado en este momento, queremos algo para aprovechar. Desafortunadamente, este es el punto en el que tanto el reflector como ILSpy me fallaron (bueno, en realidad no fue así, el sitio de llamadas está en un dll diferente (PresentationCore) que no he cargado brb). Ok, de vuelta. Una vez que buscamos en PresentationCore, tenemos una vaga idea de que dependencyProperties se registran estáticamente, por lo que encontramos el .cctor. Hay un par de líneas de interés aquí.

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

y

EventManager.RegisterClassHandler (typeof (UIElement), ManipulationCompletedEvent, nuevo manejador de sucesos (UIElement.OnManipulationCompletedThunk));

Vemos que OnManipulationCompletedThunk es la devolución de llamada registrada para este controlador de clase que escucha ManipulationCompletedEvent. Además, ManipulationCompletedEvent no se definió originalmente en UIElement, sino que se toma prestado de la clase estática Manipulation mediante AddOwner.

Al hacer una búsqueda de la clase Manipulación, veo que está en el espacio de nombres System.Windows.Input dentro del mismo ensamblaje. ¿Es público, sí? ¡Guay! así que en este momento sé que si enciendo ManipulationCompletedEvent o alguno de sus amigos, eventualmente se llamará a ScrollViewer. http://msdn.microsoft.com/en-us/library/system.windows.input.manipulation.aspx

En la documentación de esta clase estática pública, veo que hay un montón de métodos interesantes y posiblemente útiles. El único que no es fácilmente obvio es AddManipulator. ¿Qué hace esto? Clics ... lee ... oh, "cada punto de contacto es un objeto IManipulator. Por ejemplo, si usa dos dedos para cambiar el tamaño de un objeto, se crea un TouchDevice, que implementa IManipulator, para cada dedo". Entonces TouchDevice es un imanipulador. Tal vez eso me dará una idea de cómo crear mi propio manipulador.

Las Propiedades en TouchDevice dan alguna pista sobre las características que admite. Es como un MouseDevice (tiene el concepto de captura, DirectlyOver, etc.), pero no admite la manipulación de la misma manera. Más bien, queremos hacer la manipulación en respuesta a los eventos del mouse. Veamos con más detalle TouchDevice para ver cómo realmente implementa algunas de estas características.

El TouchDevice métodos está implementando son GetPosition y ManipultionEnded

GetPosition devuelve this.GetTouchPoint (relativeTo).Posición; relativeTo es un parámetro

ManipulationEnded llama OnManipulationEnded forwarding un parámetro bool llamado cancel. No estoy seguro de qué cancelar aún. oh, resulta que no se usa, raro pero está bien. Esto básicamente establece la captura como nula. Kindof al final del agujero del conejo aquí, así que tendremos que retroceder y volver a evaluar.

Todo lo que realmente quiero hacer es levantar eventos manualmente en el UIElement y ver si funciona. El método RaiseEvent en UIElement debería funcionar para esto. voy a probar brb. Err espera, me perdí de algo, todos los eventos definidos en la clase de Manipulación están marcados como internos.

Es evidente que estos eventos están destinados solo para el consumo interno, y, a falta de reflexión, no tenemos una avenida allí.

Creo que quizás usar la característica de Manipulación es excesivo para lo que estás tratando de hacer. Probablemente hay una manera de implementar esto con solo arrastrar evento y un lienzo.

Además, esto se encontró mientras se busca en Google y pensó que podría ser de alguna relevancia http://multitouchvista.codeplex.com/

Cuestiones relacionadas