animation wpf-controls expander

animation - Animate Expander en WPF



wpf-controls (2)

¿Cómo animar las acciones expandidas y contraídas de un control de expansión Wpf?


Encontré este artículo sobre Code Project: Leer aquí

El autor crea su propia Plantilla SimpleExpander y luego agrega una animación de estiramiento. Incluso le agregó una ingeniosa flecha giratoria.


Creé un estilo basado en msdn Style y el punto en esta respuesta :

<Window x:Class="Test.MainWindow" 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" xmlns:local="clr-namespace:Test" xmlns:sys="clr-namespace:System;assembly=mscorlib" xmlns:scm="clr-namespace:System.ComponentModel;assembly=WindowsBase" mc:Ignorable="d"> <Window.Resources> <Color x:Key="WindowColor">#FFE8EDF9</Color> <Color x:Key="ContentAreaColorLight">#FFC5CBF9</Color> <Color x:Key="ContentAreaColorDark">#FF7381F9</Color> <Color x:Key="DisabledControlLightColor">#FFE8EDF9</Color> <Color x:Key="DisabledControlDarkColor">#FFC5CBF9</Color> <Color x:Key="DisabledForegroundColor">#FF888888</Color> <Color x:Key="SelectedBackgroundColor">#FFC5CBF9</Color> <Color x:Key="SelectedUnfocusedColor">#FFDDDDDD</Color> <Color x:Key="ControlLightColor">White</Color> <Color x:Key="ControlMediumColor">#FF7381F9</Color> <Color x:Key="ControlDarkColor">#FF211AA9</Color> <Color x:Key="ControlMouseOverColor">#FF3843C4</Color> <Color x:Key="ControlPressedColor">#FF211AA9</Color> <Color x:Key="GlyphColor">#FF444444</Color> <Color x:Key="GlyphMouseOver">sc#1, 0.004391443, 0.002428215, 0.242281124</Color> <!--Border colors--> <Color x:Key="BorderLightColor">#FFCCCCCC</Color> <Color x:Key="BorderMediumColor">#FF888888</Color> <Color x:Key="BorderDarkColor">#FF444444</Color> <Color x:Key="PressedBorderLightColor">#FF888888</Color> <Color x:Key="PressedBorderDarkColor">#FF444444</Color> <Color x:Key="DisabledBorderLightColor">#FFAAAAAA</Color> <Color x:Key="DisabledBorderDarkColor">#FF888888</Color> <Color x:Key="DefaultBorderBrushDarkColor">Black</Color> <!--Control-specific resources.--> <Color x:Key="HeaderTopColor">#FFC5CBF9</Color> <Color x:Key="DatagridCurrentCellBorderColor">Black</Color> <Color x:Key="SliderTrackDarkColor">#FFC5CBF9</Color> <Color x:Key="NavButtonFrameColor">#FF3843C4</Color> <LinearGradientBrush x:Key="MenuPopupBrush" EndPoint="0.5,1" StartPoint="0.5,0"> <GradientStop Color="{DynamicResource ControlLightColor}" Offset="0" /> <GradientStop Color="{DynamicResource ControlMediumColor}" Offset="0.5" /> <GradientStop Color="{DynamicResource ControlLightColor}" Offset="1" /> </LinearGradientBrush> <LinearGradientBrush x:Key="ProgressBarIndicatorAnimatedFill" StartPoint="0,0" EndPoint="1,0"> <LinearGradientBrush.GradientStops> <GradientStopCollection> <GradientStop Color="#000000FF" Offset="0" /> <GradientStop Color="#600000FF" Offset="0.4" /> <GradientStop Color="#600000FF" Offset="0.6" /> <GradientStop Color="#000000FF" Offset="1" /> </GradientStopCollection> </LinearGradientBrush.GradientStops> </LinearGradientBrush> <ControlTemplate x:Key="ExpanderToggleButton" TargetType="{x:Type ToggleButton}"> <Border x:Name="Border" CornerRadius="2,0,0,0" BorderThickness="0,0,1,0"> <Border.Background> <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> <GradientStop Color="{DynamicResource ControlLightColor}" /> <GradientStop Color="{DynamicResource ControlMediumColor}" Offset="1" /> </LinearGradientBrush> </Border.Background> <Border.BorderBrush> <LinearGradientBrush StartPoint="0,0" EndPoint="0,1"> <LinearGradientBrush.GradientStops> <GradientStopCollection> <GradientStop Color="{DynamicResource BorderLightColor}" Offset="0.0" /> <GradientStop Color="{DynamicResource BorderDarkColor}" Offset="1.0" /> </GradientStopCollection> </LinearGradientBrush.GradientStops> </LinearGradientBrush> </Border.BorderBrush> <VisualStateManager.VisualStateGroups> <VisualStateGroup x:Name="CommonStates"> <VisualState x:Name="Normal" /> <VisualState x:Name="MouseOver"> <Storyboard> <ColorAnimationUsingKeyFrames Storyboard.TargetName="Border" Storyboard.TargetProperty="(Panel.Background). (GradientBrush.GradientStops)[1].(GradientStop.Color)"> <EasingColorKeyFrame KeyTime="0" Value="{StaticResource ControlMouseOverColor}" /> </ColorAnimationUsingKeyFrames> </Storyboard> </VisualState> <VisualState x:Name="Pressed"> <Storyboard> <ColorAnimationUsingKeyFrames Storyboard.TargetName="Border" Storyboard.TargetProperty="(Panel.Background). (GradientBrush.GradientStops)[1].(GradientStop.Color)"> <EasingColorKeyFrame KeyTime="0" Value="{StaticResource ControlPressedColor}" /> </ColorAnimationUsingKeyFrames> </Storyboard> </VisualState> <VisualState x:Name="Disabled"> <Storyboard> <ColorAnimationUsingKeyFrames Storyboard.TargetName="Border" Storyboard.TargetProperty="(Panel.Background). (GradientBrush.GradientStops)[1].(GradientStop.Color)"> <EasingColorKeyFrame KeyTime="0" Value="{StaticResource DisabledControlDarkColor}" /> </ColorAnimationUsingKeyFrames> <ColorAnimationUsingKeyFrames Storyboard.TargetName="Border" Storyboard.TargetProperty="(Border.BorderBrush). (GradientBrush.GradientStops)[1].(GradientStop.Color)"> <EasingColorKeyFrame KeyTime="0" Value="{StaticResource DisabledBorderLightColor}" /> </ColorAnimationUsingKeyFrames> </Storyboard> </VisualState> </VisualStateGroup> <VisualStateGroup x:Name="CheckStates"> <VisualState x:Name="Checked"> <Storyboard> <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="CollapsedArrow"> <DiscreteObjectKeyFrame KeyTime="0" Value="{x:Static Visibility.Hidden}" /> </ObjectAnimationUsingKeyFrames> <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="ExpandededArrow"> <DiscreteObjectKeyFrame KeyTime="0" Value="{x:Static Visibility.Visible}" /> </ObjectAnimationUsingKeyFrames> </Storyboard> </VisualState> <VisualState x:Name="Unchecked" /> <VisualState x:Name="Indeterminate" /> </VisualStateGroup> </VisualStateManager.VisualStateGroups> <Grid> <Path x:Name="CollapsedArrow" HorizontalAlignment="Center" VerticalAlignment="Center" Data="M 0 0 L 4 4 L 8 0 Z"> <Path.Fill> <SolidColorBrush Color="{DynamicResource GlyphColor}" /> </Path.Fill> </Path> <Path x:Name="ExpandededArrow" HorizontalAlignment="Center" VerticalAlignment="Center" Visibility="Collapsed" Data="M 0 4 L 4 0 L 8 4 Z"> <Path.Fill> <SolidColorBrush Color="{DynamicResource GlyphColor}" /> </Path.Fill> </Path> </Grid> </Border> </ControlTemplate> <Style TargetType="{x:Type Expander}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type Expander}"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="Auto" /> <RowDefinition x:Name="ContentRow" > <RowDefinition.Resources> <local:MultiplyConverter x:Key="multiplyConverter"/> </RowDefinition.Resources> <RowDefinition.Tag> <sys:Double>0.0</sys:Double> </RowDefinition.Tag> <RowDefinition.Height> <MultiBinding Converter="{StaticResource multiplyConverter}"> <Binding Path="DesiredSize.Height" ElementName="Content" /> <Binding Path="Tag" RelativeSource="{RelativeSource Self}" /> </MultiBinding> </RowDefinition.Height> </RowDefinition> </Grid.RowDefinitions> <VisualStateManager.VisualStateGroups> <VisualStateGroup x:Name="CommonStates"> <VisualState x:Name="Normal" /> <VisualState x:Name="MouseOver" /> <VisualState x:Name="Disabled"> <Storyboard> <ColorAnimationUsingKeyFrames Storyboard.TargetName="Border" Storyboard.TargetProperty="(Panel.Background). (GradientBrush.GradientStops)[1].(GradientStop.Color)"> <EasingColorKeyFrame KeyTime="0" Value="{StaticResource DisabledControlDarkColor}" /> </ColorAnimationUsingKeyFrames> <ColorAnimationUsingKeyFrames Storyboard.TargetName="Border" Storyboard.TargetProperty="(Border.BorderBrush). (GradientBrush.GradientStops)[1].(GradientStop.Color)"> <EasingColorKeyFrame KeyTime="0" Value="{StaticResource DisabledBorderLightColor}" /> </ColorAnimationUsingKeyFrames> </Storyboard> </VisualState> </VisualStateGroup> </VisualStateManager.VisualStateGroups> <Border x:Name="Border" Grid.Row="0" BorderThickness="1" CornerRadius="2,2,0,0"> <Border.BorderBrush> <LinearGradientBrush EndPoint="0,1" StartPoint="0,0"> <GradientStop Color="{DynamicResource BorderLightColor}" Offset="0" /> <GradientStop Color="{DynamicResource BorderDarkColor}" Offset="1" /> </LinearGradientBrush> </Border.BorderBrush> <Border.Background> <LinearGradientBrush StartPoint="0,0" EndPoint="0,1"> <LinearGradientBrush.GradientStops> <GradientStopCollection> <GradientStop Color="{DynamicResource ControlLightColor}" Offset="0.0" /> <GradientStop Color="{DynamicResource ControlMediumColor}" Offset="1.0" /> </GradientStopCollection> </LinearGradientBrush.GradientStops> </LinearGradientBrush> </Border.Background> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="20" /> <ColumnDefinition Width="*" /> </Grid.ColumnDefinitions> <ToggleButton OverridesDefaultStyle="True" Template="{StaticResource ExpanderToggleButton}" IsChecked="{Binding IsExpanded, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"> <ToggleButton.Background> <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> <GradientStop Color="{DynamicResource ControlLightColor}" Offset="0" /> <GradientStop Color="{DynamicResource ControlMediumColor}" Offset="1" /> </LinearGradientBrush> </ToggleButton.Background> </ToggleButton> <ContentPresenter Grid.Column="1" Margin="4" ContentSource="Header" RecognizesAccessKey="True" /> </Grid> </Border> <Border x:Name="Content" Grid.Row="1" BorderThickness="1,0,1,1" CornerRadius="0,0,2,2"> <Border.BorderBrush> <SolidColorBrush Color="{DynamicResource BorderMediumColor}" /> </Border.BorderBrush> <Border.Background> <SolidColorBrush Color="{DynamicResource ContentAreaColorDark}" /> </Border.Background> <ContentPresenter Margin="4" /> </Border> </Grid> <ControlTemplate.Triggers> <Trigger Property="IsExpanded" Value="True"> <Trigger.EnterActions> <BeginStoryboard> <Storyboard> <DoubleAnimation Storyboard.TargetName="ContentRow" Storyboard.TargetProperty="Tag" From="0" To="1" Duration="0:0:1"/> </Storyboard> </BeginStoryboard> </Trigger.EnterActions> <Trigger.ExitActions> <BeginStoryboard> <Storyboard> <DoubleAnimation Storyboard.TargetName="ContentRow" Storyboard.TargetProperty="Tag" From="1" To="0" Duration="0:0:1"/> </Storyboard> </BeginStoryboard> </Trigger.ExitActions> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style> </Window.Resources> <StackPanel> <Expander Header="Canny" > <StackPanel> <Button Content="A" /> <Button Content="B" /> <Button Content="C" /> </StackPanel> </Expander> <Expander Header="Sobel" > <StackPanel> <Button Content="A" /> <Button Content="B" /> <Button Content="C" /> </StackPanel> </Expander> <Expander Header="LoG" > <StackPanel> <Button Content="A" /> <Button Content="B" /> <Button Content="C" /> </StackPanel> </Expander> </StackPanel> </Window>

Lo que requiere este convertidor:

public class MultiplyConverter : IMultiValueConverter { public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) { return new GridLength((double)values[0] * (double)values[1], GridUnitType.Pixel); } public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) { throw new NotImplementedException(); } }

El punto principal es establecer DoubleAnimation en ContentRow.Height en la plantilla. Sin embargo, debe utilizar un MultiBinding para enlazar la propiedad To de esta animación.