c# wpf silverlight silverlight-4.0 visualstatemanager

c# - ¿Cómo esperar a que finalice la transición de cambio de estado en Silverlight 4?



wpf silverlight-4.0 (3)

La forma correcta de manejar este problema sería escuchando el evento CurrentStateChanged en VisualStateGroup, pero desde mi experiencia no es confiable en el mejor de los casos y se rompe en el peor.

La segunda opción es enlazar el evento Completado en su Guión Gráfico, pero esta opción obtuvo sus propias dificultades. En algunos casos, el administrador de estado visual genera animaciones internamente, por lo que el evento Completed you set no se ejecutará.

Necesito cambiar el estado de un control y luego hacer algo de acción. Para ser específico, quiero ejecutar una animación antes de que se oculte un control. Me gustaría hacer algo como eso:

VisualStateManager.GoToState(control, "Hidden", true); // wait until the transition animation is finished ParentControl.Children.Remove(control);

El problema es que la animación de transición se ejecuta de forma asíncrona y, por lo tanto, el control se elimina del árbol visual justo después de que se inicia la animación.

Entonces, ¿cómo espero a que termine la animación?


Puede adjuntar un controlador de eventos Storyboard.Completed al Storyboard o adjuntar un controlador de eventos VisualStateGroup.CurrentStateChanged al VisualStateGroup:

<UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" x:Class="SilverlightApplication7.MainPage" Width="640" Height="480"> <Grid x:Name="LayoutRoot" Background="White"> <VisualStateManager.VisualStateGroups> <VisualStateGroup x:Name="VisualStateGroup" > <VisualState x:Name="Hidden"> <Storyboard Completed="OnHidden"> <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="rectangle" d:IsOptimized="True"/> </Storyboard> </VisualState> </VisualStateGroup> </VisualStateManager.VisualStateGroups> <Rectangle x:Name="rectangle" Fill="#FFF4F4F5" HorizontalAlignment="Left" Height="136" Margin="48,72,0,0" Opacity="0" Stroke="Black" VerticalAlignment="Top" Width="208"/> </Grid>

using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; namespace SilverlightApplication7 { public partial class MainPage : UserControl { public MainPage() { // Required to initialize variables InitializeComponent(); this.Loaded += new RoutedEventHandler(MainPage_Loaded); } void MainPage_Loaded(object sender, RoutedEventArgs e) { VisualStateManager.GoToState(this, "Hidden", true); } private void OnHidden(object storyboard, EventArgs args) { } }

}


De hecho, es posible adjuntar el controlador completado en el código:

Collection<VisualStateGroup> grps = (Collection<VisualStateGroup>)VisualStateManager.GetVisualStateGroups(this.LayoutRoot); foreach (VisualStateGroup grp in grps) { Collection<VisualState> states = (Collection<VisualState>)grp.States; foreach (VisualState state in states) { switch (state.Name) { case "Intro": state.Storyboard.Completed += new EventHandler(Intro_Completed);break; } } }

Ejemplo de este hilo: http://forums.silverlight.net/forums/p/38027/276746.aspx

Trabajando para mí en un proyecto en vivo usando Comportamiento adjunto también! Sin embargo, un poco molesto que tuve que usar propiedades de dependencia separadas para el UserControl raíz (para usar en VisualStateManager.GoToState) y el LayoutRoot para obtener la colección real de VisualStateGroup.