如何在WPF中为控件实现缩小动画

时间:2014-02-14 16:29:47

标签: wpf xaml animation

我希望控件(例如GroupBox)在可见时显示增长动画,并在可见性更改为“折叠”时显示缩小动画。

因此,我创建了一个实现动画生长和缩小效果的样式,如下面的小样本应用程序所示(如下所示)。

但是,仅显示增长动画。组合框不会显示收缩动画,而是立即消失。

谁能告诉我,为什么? 甚至更好,如何解决它?

<Window x:Class="ShrinkTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <Style TargetType="FrameworkElement" x:Key="ExpandableElement">
            <Setter Property="RenderTransformOrigin" Value="0.5 0" />
            <Setter Property="RenderTransform">
                <Setter.Value>
                    <ScaleTransform/>
                </Setter.Value>
            </Setter>
            <Style.Triggers>
                <Trigger Property="Visibility" Value="Visible">
                    <Trigger.EnterActions>
                        <BeginStoryboard>
                            <Storyboard>
                                <DoubleAnimation Storyboard.TargetProperty="RenderTransform.ScaleY" From="0" To="1" Duration="0:0:0.5" AccelerationRatio="0.2" DecelerationRatio="0.4"/>
                            </Storyboard>
                        </BeginStoryboard>
                    </Trigger.EnterActions>
                </Trigger>
                <Trigger Property="Visibility" Value="Hidden">
                    <Trigger.EnterActions>
                        <BeginStoryboard>
                            <Storyboard>
                                <DoubleAnimation Storyboard.TargetProperty="RenderTransform.ScaleY" From="1" To="0" Duration="0:0:0.5" AccelerationRatio="0.2" DecelerationRatio="0.4"/>
                            </Storyboard>
                        </BeginStoryboard>
                    </Trigger.EnterActions>
                </Trigger>
            </Style.Triggers>
        </Style>
    </Window.Resources>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <Button Grid.Row="0" Margin="8" Width="140" Click="ButtonBase_OnClick">Expand / Shrink</Button>

        <TextBlock Grid.Row="1" Text="--- Header ---"/>

        <GroupBox x:Name="GroupBox" Grid.Row="2" Header="GroupBox" Style="{StaticResource ExpandableElement}" >
            <StackPanel Orientation="Vertical">
                <TextBlock Text="Test Test Test"/>
                <TextBlock Text="Test Test Test"/>
                <TextBlock Text="Test Test Test"/>
                <TextBlock Text="Test Test Test"/>
                <TextBlock Text="Test Test Test"/>
            </StackPanel>
        </GroupBox>

        <TextBlock Grid.Row="3" Text="--- Footer ---"/>
    </Grid>
</Window>

2 个答案:

答案 0 :(得分:0)

我有类似的问题。只需考虑一下......你的问题是你可以看到你的动画,但是当你的动画被隐藏时你就不能看到它。 也是你解释原因的答案......因为它是隐藏的。我知道,这是一个相当令人不满意的答案,但事实就是如此。

关于如何解决它...好吧说它很简单,但实现它不是。简而言之,您必须运行动​​画直到结束,然后Visibility设置为Hidden。所以不幸的是,这意味着设置Visibility TriggerVisibility属性的简单设置已经不再可行......可以将其显示为可见,而不是为了隐藏。

在我的情况下,我有一个完整的框架,我构建了我的动画。基本上,当我从集合中删除项目时,内部的项目实际上并未被删除,而是启动了退出动画。只有当该动画完成时,内部集合才会删除该项目。

因此,如果您感到困扰,那么您必须实现类似这样的内容,而不是将Hidden属性设置为true,而是将另一个属性设置为Completed触发动画,当调用该动画中的Visibility事件时,然后Hidden属性设置为{{1}}。

答案 1 :(得分:0)

谢里丹是对的。一旦控件变得不可见,无关紧要,您应用哪个动画。 : - )

所以我创建了一个特殊的ExpandingContentControl:

public class ExpandingContentControl : ContentControl
{
    public static readonly DependencyProperty IsExpandedProperty = DependencyProperty.Register(
        "IsExpanded", typeof(bool), typeof(ExpandingContentControl), new PropertyMetadata(false));

    public bool IsExpanded
    {
        get { return (bool)GetValue(IsExpandedProperty); }
        set { SetValue(IsExpandedProperty, value); }
    }

    public ExpandingContentControl()
    {
        Visibility = IsExpanded ? Visibility.Visible : Visibility.Collapsed;
    }
}

但是样式也存在问题:创建两个绑定到同一属性的不同值的触发器显然不起作用。 相反,我现在只使用一个触发器,其中EnterAction实现增长,而ExitAction实现缩小控件:

<Style TargetType="controls:ExpandingContentControl" >
    <Setter Property="RenderTransformOrigin" Value="0.5 1" />
    <Setter Property="RenderTransform">
        <Setter.Value>
            <ScaleTransform/>
        </Setter.Value>
    </Setter>
    <Style.Triggers>
        <Trigger Property="IsExpanded" Value="True">
            <Trigger.EnterActions>
                <BeginStoryboard>
                    <Storyboard>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" >
                            <DiscreteObjectKeyFrame Value="{x:Static Visibility.Visible}" KeyTime="00:00:00"/>
                        </ObjectAnimationUsingKeyFrames>
                        <DoubleAnimation Storyboard.TargetProperty="RenderTransform.ScaleY" From="0" To="1" 
                                         Duration="0:0:0.3" DecelerationRatio="0.4"/>
                    </Storyboard>
                </BeginStoryboard>
            </Trigger.EnterActions>
            <Trigger.ExitActions>
                <BeginStoryboard>
                    <Storyboard>
                        <DoubleAnimation Storyboard.TargetProperty="RenderTransform.ScaleY" From="1" To="0" Duration="0:0:0.2" />
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility">
                            <DiscreteObjectKeyFrame Value="{x:Static Visibility.Collapsed}" KeyTime="00:00:0.2"/>
                        </ObjectAnimationUsingKeyFrames>
                    </Storyboard>
                </BeginStoryboard>
            </Trigger.ExitActions>
        </Trigger>
    </Style.Triggers>
</Style>