2012-09-28 16 views
5

He creado una aplicación de Windows 8 Store usando C#/XAML. Mi interfaz incluye una lista desplazable, que se representa utilizando un ScrollViewer. Me gustaría poder manejar eventos de manipulación en los elementos dentro de la lista; sin embargo, establecer ManipulationMode en cualquier elemento que no sea None en el elemento list hace que mi lista deje de desplazarse.ScrollViewer y manejo de eventos de manipulación en elementos secundarios

Aquí es una versión simplificada de la interfaz de usuario:

<ScrollViewer> 
    <Border/> <!-- these contain child content --> 
    <Border/> 
    <Border/> 
    <!-- Set ManipulationMode on an element in order to receive manipulation events --> 
    <!-- This causes the scroll viewer to stop working! --> 
    <Border ManipulationMode="All" 
      ManipulationDelta="..."/> 
    <Border/> 
    <Border/> 
</ScrollViewer> 

entiendo que la WinRT ScrollViewer utiliza un especial ManipulationMode de System por razones de rendimiento, pero me gustaría tener una lista de desplazamiento vertical, que contiene elementos que responder a la manipulación/gestos horizontales. ¿Alguien puede pensar en una solución creativa que lo haga posible?

Respuesta

8

Lo que he hecho fue colocar un rectángulo transparente encima del ScrollViewer y manejar manipulaciones allí. Cuando encuentre que la manipulación debe desplazar el ScrollViewer, desplazo el ScrollViewer usando los métodos ScrollToHorizontal/VerticalOffset(). En ManipulationStarted también uso VisualTreeHelper.FindElementsInHostCoordinates para verificar qué elemento puedo manipular también y luego puedo decidir si manipular ese elemento o no, dependiendo de varias condiciones. Sin embargo, es un código bastante personalizado. También necesitaría actualizar RenderTransform del ScrollContentPresenter en ScrollViewer cuando el usuario intente arrastrar más allá del desplazamiento mínimo/máximo para imitar el comportamiento predeterminado de ScrollViewer, manejar la rueda de desplazamiento del mouse, etc. Nada que USTED no pueda manejar, por supuesto. Desafortunadamente no pude encontrar una mejor manera y estoy interesado si alguien encuentra uno.

EDITAR * Otra solución en la que pensé cuando intenté responder a another similar question fue utilizar otro ScrollViewer como elemento secundario y usar sus eventos ViewChanged en lugar de eventos de manipulación.

EDIT 2 *

también con Windows 8.1 que presentamos lo ManipulationModes.System que combinado con otros modos debe permitir que usted resuelva manipulaciones en el interior de un ScrollViewer. A continuación, puede llamar al CancelDirectManipulations() en el elemento manipulado una vez que desea que su padre ScrollViewers pare las manipulaciones de procesamiento para el zoom pan &.

+0

Guau, eso es mucho trabajo. ¿Entonces básicamente se ocupa de desplazar el 'ScrollViewer' usted mismo? ¿Esto significa que también debe realizar sus propios cálculos de inercia para que se desplace de forma natural? ¿O lo hace automáticamente cuando cambia el desplazamiento vertical? – ColinE

+1

Las manipulaciones en Júpiter tienen una inercia incorporada habilitada por defecto, por lo que se cubre. Solo debe asegurarse de no aplastar ScrollContentPresenter al final de la lista si el desplazamiento ocurre debido a la inercia. Las manipulaciones suelen ser bastante suaves, pero probablemente podría utilizar animaciones ScrollViewer como las del [WinRT XAML Toolkit] (http://bit.ly/WinRTXamlToolkit) para suavizar el desplazamiento cuando se usa la rueda de desplazamiento. Por cierto, me olvidé de mencionar que también es posible que desee manejar la configuración de enfoque en los elementos cuando toca en la superposición ... :) –

+1

@ColinE verifique mi respuesta a [esta pregunta] (http: // stackoverflow.com/questions/14153038/how-to-allow-manipulations-within-listview-gridview-item-controls-while-allow/14161596 # 14161596) para otra solución. –

10

puede tardar mucho tiempo pero no encontró ninguna solución. Acabo de lograr lo que quería muy fácilmente.

public MovableGrid() 
     { 
      ManipulationMode = ManipulationModes.TranslateX | ManipulationModes.System; 
      AddHandler(ManipulationDeltaEvent, new ManipulationDeltaEventHandler(UIElement_OnManipulationDelta), true); 
      AddHandler(ManipulationCompletedEvent, new ManipulationCompletedEventHandler(UIElement_OnManipulationCompleted), true); 
     } 

quería mi MovableGrid que ser trasladado en el eje X y tengo lista de MovableGrids la que yo quería ser desplazado con ScrollViewer. Eso es suficiente para hacer eso.

+0

¡Gracias! Esto es exactamente lo que necesitaba! – Pam

Cuestiones relacionadas