2010-06-04 3 views
5

¿Alguien sabe si es posible activar una animación cuando se cierra un ContextMenu de WPF?¿Cómo disparo una animación de cierre para un ContextMenu de WPF?

Tengo un código que desencadena una animación cuando se abre el ContextMenu. La animación hace que el menú contextual se desvanezca a la vista. También quiero una animación cuando el ContextMenu está cerrado y hace que se desvanezca.

El código abierto que inicia el fundido de animación se ve algo como esto:

 var animation = new DoubleAnimation(); 
     animation.From = 0; 
     animation.To = 1; 
     animation.Duration = TimeSpan.FromSeconds(0.2); 
     animation.Freeze(); 

     menu.BeginAnimation(ContextMenu.OpacityProperty, animation); 

El fundido de la animación también se ejecuta en elementos del submenú.

Tenga en cuenta que también quiero ejecutar otras animaciones, además de desvanecerse y desaparecer. Por ejemplo, quiero que el menú contextual se amplíe de la nada para que aparezca como 'rebote'.

+0

¿Puedes publicar el código de animación cuando se abre el menú contextual? – Amsakanna

Respuesta

0

no se es capaz de utilizar el evento ContextMenuClosing

+0

¡Desafortunadamente ese evento es demasiado tarde! Puedo comenzar la animación de fundido de salida, pero no tiene ningún efecto porque el menú contextual desaparece de inmediato. –

7

Aparte de Popup.PopupAnimation, no hay gancho dentro ContextMenu o emergente que le permite retrasar el desmantelamiento de la ContextMenu, la destrucción de la ventana, etc., el tiempo suficiente para mostrar tu animación. Esto le deja con varias opciones:

  1. Puede utilizar Popup.PopupAnimation a retrasar el cierre de ventanas emergentes, luego vuelva a su animación con su propia,
  2. Puede presentar el ContextMenu en su propia emergente en ContextMenuClosing, juega bien sus animación, y extraerla
  3. Usted puede implementar su propio código para manejar botón derecho del ratón, Shift-F10, etc para crear la ventana emergente y mostrar el ContextMenu dentro de ella

Usando Popup.PopupAnimation

En el evento ContextMenuOpened, busque la ventana emergente y establezca Popup.PopupAnimation en cualquier animación, luego supervise Popup.IsOpen y cuando la propiedad IsOpen sea falsa, use una devolución de llamada de Dispatcher para reemplazar la animación programada por la suya. Su animación puede reutilizar el TranslateTransform creado por la clase Popup o puede agregar su propia transformación.

Esta tecnología es simple y compatible, pero el inconveniente es que no tiene control sobre la duración del intervalo (fijo) entre el momento en que la ventana emergente decide cerrarse y el momento en que todo se desmantela. Parece ser aproximadamente 1/6 de segundo, así que si puedes vivir con eso, este es probablemente el camino a seguir.

Usando su propio emergente para mostrar el ContextMenu durante el cierre de animación

Por el momento te ContextMenuClosing la ventana emergente que estaba mostrando el menú ya se ha ido, pero puede crear temporalmente una nueva.

Para evitar el parpadeo, esto debe hacerse en DisplachPriority.Render o superior. Además, el nuevo Popup debe estar exactamente en la misma posición y tamaño que el creado durante el menú emergente. Estas coordenadas se pueden grabar inmediatamente después del evento ContextMenuOpened. Tendrá que hacer esto en una devolución de llamada de Dispatcher porque las coordenadas no están realmente disponibles durante el evento ContextMenuOpened.

lo tanto, el procedimiento es el siguiente:

  • En ContextMenuOpened, hacer un Dispatcher.BeginInvoke de una acción que registra la posición y el tamaño emergente.
  • En ContextMenuClosed, hacer un Dispatcher.BeginInvoke de una acción que construye una ventana emergente en esa posición y tamaño cuyo hijo es el ContextMenu, establece su IsOpen cierto, comienza la animación
  • Cuando los extremos de animación (esto se puede hacer usando un temporizador), establezca IsOpen de Popup falso y borre su propiedad Child
  • No se olvide de asegurarse de que DataContext del ContextMenu esté configurado correctamente durante el tiempo de animación para que muestre los mismos datos que antes de que se cerrara el ContextMenu.

implementar su propio código de manejo ContextMenu

Si marca su ContextMenuEventArgs.Handled cierto en el caso ContextMenuOpened, el código ContextMenu en realidad no hace nada, lo que le permite presentar la ContextMenu mismo. Para ello:

  1. construir un emergente, calcular la ubicación apropiada (! Este es definitivamente no trivial), y añadir el ContextMenu como su niño
  2. Ajuste el Popup.IsOpen verdadera y comenzar su animación de apertura
  3. cuando es hora de que el ContextMenu para cerrar, se inicia la animación de cierre, a continuación, establezca Popup.IsOpen falsa y borrar su propiedad niño

la parte difícil es decidir de esta forma fiable cuando para cerrar el ContextMenu (paso 3) basado en acciones del usuario. No conozco ninguna forma de reutilizar los mecanismos incorporados de NET Framework para esto y las reglas para cuando el ContextMenu debería cerrarse son bastante complejas.

+0

Gracias por una respuesta muy detallada, lo intentaré y aplicaré a mi código pronto. –

+0

Doble gracias por los detalles. – scobi

Cuestiones relacionadas