Animación en visibilidad de oculta a colapsada y viceversa

Estoy tratando de lograr algo similar a la vista de mensajes de iPhone. Al hacer clic en un botón, un botón de eliminación se deslizaría hacia afuera para cada mensaje y al hacer clic en "Listo", los botones de eliminación se deslizarían hacia adentro. Pude lograr eso usando mvvm excepto el corredizo efecto. Aquí está el estilo que podría escribir con mi conocimiento limitado:

<Style TargetType="Border">
    <Style.Triggers>
        <DataTrigger Binding="{Binding ShowDeleteButton}" Value="false">
            <Setter Property="Visibility" Value="Collapsed"/>
        </DataTrigger>
    </Style.Triggers>
</Style>

Aquí "ShowDeleteButton" es una propiedad bool en el modelo de vista. Esto funciona bien. pero el colapso y "hacerse visible" está ocurriendo abruptamente y muy rápido. Necesito un poco de animación deslizante. Tenga en cuenta que a medida que desaparecen los botones de eliminación, el resto de los controles deben ocupar el resto del espacio y, a medida que aparece el botón, los controles existentes deben reducirse y dar espacio a los botones. Probé con la animación del guión gráfico, pero incluso después de un par de horas no puedo descifrar los extraños errores que arroja. Aquí está el código:

<DataTrigger Binding="{Binding ShowDeleteButton}" Value="false">
     <DataTrigger.EnterActions>
          <BeginStoryboard>
               <Storyboard BeginTime="0:0:1">
                  <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visiblity">
                     <DiscreteObjectKeyFrame Value="{x:Static Visibility.Collapsed}" />
                  </ObjectAnimationUsingKeyFrames>
                </Storyboard>
           </BeginStoryboard>
      </DataTrigger.EnterActions>
      <DataTrigger.ExitActions>
            <BeginStoryboard>
               <Storyboard BeginTime="0:0:1">
                 <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visiblity">
                     <DiscreteObjectKeyFrame Value="{x:Static Visibility.Visible}" />
                 </ObjectAnimationUsingKeyFrames>
               </Storyboard>
            </BeginStoryboard>
      </DataTrigger.ExitActions>
</DataTrigger>

¿Puede alguien por favor ayudar al alma en apuros?

Saludos

preguntado el 22 de mayo de 12 a las 13:05

1 Respuestas

Vieja pregunta... eh...

De todos modos... olvídate de la visibilidad. El truco es animar. Width/Height del Control colocado en Grid's Column/Row donde el Column/Row tiene Ancho establecido en Auto. Uff :)

Así que aquí hay un Grid llamado "contenedor" con dos columnas. En la primera columna se puede colocar lo que quieras, pero debes alinearlo a la derecha ya que quieres que se mueva cuando se muestra el botón Eliminar. Y en la segunda columna hay un Control (que representa su botón Eliminar) Observe que la primera columna tiene Width="*" y la segunda columna tiene Width="Auto"

<Grid Background="Purple" Width="350" Height="100">
    <CheckBox Content="Show" IsChecked="{Binding Path=ShowDeleteButton}" Height="16" HorizontalAlignment="Left" Margin="12,12,0,0" Name="checkBox1" VerticalAlignment="Top" />
    <Grid x:Name="container" Margin="40,0,0,0">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="Auto"/>
        </Grid.ColumnDefinitions>
        <Grid Name="content" Margin="0">
            <Label Content="Look I'm flyin'!" Margin="0,30,10,0" VerticalAlignment="Top" HorizontalAlignment="Right"/>
        </Grid>
        <Control Grid.Column="1" Margin="0">
            <Control.Template>
                <ControlTemplate>
                    <ControlTemplate.Triggers>
                        <DataTrigger Binding="{Binding ShowDeleteButton}" Value="true">
                            <DataTrigger.EnterActions>
                                <BeginStoryboard>
                                    <Storyboard>
                                        <DoubleAnimation 
                                Storyboard.TargetName="flyout"
                                Storyboard.TargetProperty="(Grid.Width)" 
                                From="0" To="120" Duration="0:0:1" AutoReverse="False"/>
                                    </Storyboard>
                                </BeginStoryboard>
                            </DataTrigger.EnterActions>
                            <DataTrigger.ExitActions>
                                <BeginStoryboard>
                                    <Storyboard>
                                        <DoubleAnimation 
                                Storyboard.TargetName="flyout"
                                Storyboard.TargetProperty="(Grid.Width)" 
                                From="120" To="0" Duration="0:0:1" AutoReverse="False"/>
                                    </Storyboard>
                                </BeginStoryboard>
                            </DataTrigger.ExitActions>
                        </DataTrigger>
                    </ControlTemplate.Triggers>
                    <Grid x:Name="flyout" Width="0">
                        <Rectangle Fill="Green"/>
                        <Label Content="I'm DELETE button" Margin="10,30,0,0" VerticalAlignment="Top"/>
                    </Grid>
                </ControlTemplate>
            </Control.Template>
        </Control>
    </Grid>
</Grid>

En los Control en la segunda columna de Grid tiene DataTrigger basado en la propiedad de su ViewModel "MostrarBotónEliminar"

Puesto que el Width de columna donde Control se coloca es Auto puede cambiar el ancho de la Control usando simple DoubleAnimation y obtienes el comportamiento deseado.

EDITAR

Mira esto si quieres que el control flotante esté por encima de todo lo demás.

<Grid x:Name="LayoutRoot">
    <Grid x:Name="container" Width="120" HorizontalAlignment="Right">
            <Button x:Name="button" Content="In" Margin="0,13,7.5,0" VerticalAlignment="Top" HorizontalAlignment="Right" d:LayoutOverrides="HorizontalAlignment">
                <Button.Triggers>
                    <EventTrigger RoutedEvent="Button.Click">
                        <BeginStoryboard>
                            <Storyboard>
                                <DoubleAnimation 
                                    Storyboard.TargetName="flyout"
                                    Storyboard.TargetProperty="(Grid.Width)" 
                                    From="0" To="120" Duration="0:0:1" AutoReverse="False"/> 
                            </Storyboard>
                        </BeginStoryboard>
                    </EventTrigger>
                </Button.Triggers>
            </Button>
    </Grid>
    <Grid x:Name="flyout" Width="120" Margin="0" HorizontalAlignment="Right">
            <Rectangle Fill="Green"/>
            <Label Content="This is some label" Margin="6.038,27,1.006,0" VerticalAlignment="Top"/>
            <Button Content="Out" Margin="11.917,58,0,0" VerticalAlignment="Top" HorizontalAlignment="Left" Width="80.083">
                <Button.Triggers>
                    <EventTrigger RoutedEvent="Button.Click">
                        <BeginStoryboard>
                            <Storyboard>
                                <DoubleAnimation 
                                    Storyboard.TargetName="flyout"
                                    Storyboard.TargetProperty="(Grid.Width)" 
                                    From="120" To="0" Duration="0:0:1" AutoReverse="False"/> 
                            </Storyboard>
                        </BeginStoryboard>
                    </EventTrigger>
                </Button.Triggers>
            </Button>
        </Grid>
</Grid>

Tenga en cuenta que se puede hacer clic en el botón "Fuera" mientras se está moviendo. Probablemente debería estar deshabilitado. Simplemente lo hice así porque quería hacerlo simple y todo en xaml. Seguro que puedes usar mahapps. O simplemente puede hacerlo tan rápido como en MahApps y es imposible hacer clic dos veces. :) He mirado MahApps FlyOutDemo y mi solución me parece mucho más simple. Y no necesito una biblioteca de terceros.

respondido 18 mar '13, 13:03

¡Gracias @Viktor! Sin embargo, esto no es exactamente lo que quería. Este enfoque en realidad está cambiando el tamaño de mi vista existente para acomodar la nueva vista. Sin embargo, quería un control flotante que pasara por encima de la vista existente. MahApps metro ofrece uno de esos controles. :) ¡Sin embargo, aprecio tu esfuerzo por responder la pregunta anterior! Salud.. - James

@James, entonces, ¿qué significa esto? "a medida que aparece el botón, los controles existentes deberían reducirse y dar espacio a los botones". Si no desea eso, el enfoque podría ser el mismo ... animar el ancho en la cuadrícula con ancho automático. Si no puedes manejar eso, puedo mirarlo una vez más. He probado MahApps.Metro... no me gusta. :) - Capitán Mlíko

Hola @Viktor, gracias de nuevo, intentaré esto. Por cierto, ¿te importa decirme qué es lo que hace que no te gusten las MahApps? Una cosa es segura por mi parte, no proporcionan estilos para la cuadrícula de datos y el selector de fecha. ¿Cuáles son las razones por tu parte? - James

¡Funciona de maravilla! Sin embargo, lo había resuelto mucho antes, del tutorial aquí: youtube.com/watch?v=Kkr4DtVOYmI Sin embargo, agradezco el esfuerzo que hizo para responder a la pregunta. Saludos Víctor! - James

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.