xaml - 如何使用视觉状态为 UWP 中控件的可见性设置动画?

标签 xaml animation uwp visualstatemanager

我目前正在为我的应用程序开发一个自定义控件,该控件使用标题展开和折叠内容,您可以单击该标题更改状态。它的模板目前看起来像这样。

<Style TargetType="controls:ExpandControl">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="controls:ExpandControl">
                <Border>
                    <VisualStateManager.VisualStateGroups>
                        <VisualStateGroup x:Name="State">
                            <VisualState x:Name="Visible">
                                <VisualState.Setters>
                                    <Setter Target="Grid.Visibility" Value="Visible" />
                                </VisualState.Setters>
                            </VisualState>

                            <VisualState x:Name="Collapsed">
                                <VisualState.Setters>
                                    <Setter Target="Grid.Visibility" Value="Collapsed" />
                                </VisualState.Setters>
                            </VisualState>
                        </VisualStateGroup>
                    </VisualStateManager.VisualStateGroups>

                    <Grid>
                        <Grid.RowDefinitions>
                            <RowDefinition Height="Auto" />
                            <RowDefinition Height="*" />
                        </Grid.RowDefinitions>

                        <ContentPresenter x:Name="HeaderPresenter" Content="{TemplateBinding Header}" />

                        <Grid x:Name="Grid" Grid.Row="1">
                            <ContentPresenter x:Name="ContentPresenter" Content="{TemplateBinding Content}" />
                        </Grid>
                    </Grid>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

正如您从模板中看到的,我目前正在使用视觉状态来设置此控件中内容的可见性,但这并不是很好的用户体验,因为内容只是消失了。

我希望能够以某种方式操纵内容,当控件的 Visibility 发生变化时,允许内容看起来像是从标题折叠和展开。

我已经使用 Storyboards 查看了动画,但我对此完全陌生,如果有人可以提供有关 Storyboards 的帮助以及如何使场景适合我的控制,我将不胜感激!

提前致谢!

最佳答案

Storyboard在 Visual Studio 中并不是一种出色的体验,尝试手动编写它们可能不是最好的主意。

我建议在 Blend 中打开你的项目,它是你的 Visual Studio 安装的一部分。它是设计应用程序的绝佳工具,尤其是以非常简单的方式添加 Storyboard,它会在您看到设计器中的更改时自动为您生成 Storyboard XAML。

至于你的动画场景,我在页面中使用了你的 XAML 模板,并提出了一些让它看起来像折叠和展开的东西,但它没有像这样操作 Visibility 属性:

<VisualStateGroup x:Name="State">
    <VisualState x:Name="Visible">
        <Storyboard>
            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="Grid">
                <EasingDoubleKeyFrame KeyTime="0" Value="0"/>
                <EasingDoubleKeyFrame KeyTime="0:0:0.2" Value="0"/>
                <EasingDoubleKeyFrame KeyTime="0:0:0.3" Value="1"/>
            </DoubleAnimationUsingKeyFrames>
            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.ScaleY)" Storyboard.TargetName="Grid">
                <EasingDoubleKeyFrame KeyTime="0" Value="0"/>
                <EasingDoubleKeyFrame KeyTime="0:0:0.3" Value="1"/>
            </DoubleAnimationUsingKeyFrames>
            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="Grid">
                <DiscreteObjectKeyFrame KeyTime="0">
                    <DiscreteObjectKeyFrame.Value>
                        <Visibility>Collapsed</Visibility>
                    </DiscreteObjectKeyFrame.Value>
                </DiscreteObjectKeyFrame>
                <DiscreteObjectKeyFrame KeyTime="0:0:0.1">
                    <DiscreteObjectKeyFrame.Value>
                        <Visibility>Visible</Visibility>
                    </DiscreteObjectKeyFrame.Value>
                </DiscreteObjectKeyFrame>
            </ObjectAnimationUsingKeyFrames>
        </Storyboard>
    </VisualState>

    <VisualState x:Name="Collapsed">
        <Storyboard>
            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="Grid">
                <EasingDoubleKeyFrame KeyTime="0" Value="1"/>
                <EasingDoubleKeyFrame KeyTime="0:0:0.1" Value="0"/>
            </DoubleAnimationUsingKeyFrames>
            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.ScaleY)" Storyboard.TargetName="Grid">
                <EasingDoubleKeyFrame KeyTime="0" Value="1"/>
                <EasingDoubleKeyFrame KeyTime="0:0:0.3" Value="0"/>
            </DoubleAnimationUsingKeyFrames>
            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="Grid">
                <DiscreteObjectKeyFrame KeyTime="0">
                    <DiscreteObjectKeyFrame.Value>
                        <Visibility>Visible</Visibility>
                    </DiscreteObjectKeyFrame.Value>
                </DiscreteObjectKeyFrame>
                <DiscreteObjectKeyFrame KeyTime="0:0:0.2">
                    <DiscreteObjectKeyFrame.Value>
                        <Visibility>Collapsed</Visibility>
                    </DiscreteObjectKeyFrame.Value>
                </DiscreteObjectKeyFrame>
            </ObjectAnimationUsingKeyFrames>
        </Storyboard>
    </VisualState>
</VisualStateGroup>

您还需要将内容网格更改为如下所示:
<Grid x:Name="Grid" Grid.Row="1" RenderTransformOrigin="0.5,0">
    <Grid.RenderTransform>
        <CompositeTransform/>
    </Grid.RenderTransform>

    <ContentPresenter x:Name="ContentPresenter" Content="{TemplateBinding Content}" />
</Grid>

我将解释为什么您必须对网格进行更改以及 Storyboard接下来要做什么。

为了实现与您正在寻找的类似的东西,我选择了网格上的不透明度和 Y 比例来制作动画。

因为我们将操纵控件的 Y 比例,所以我们将 RenderTransform 添加到网格。使用 CompositeTransform 的原因是您可以操作最常见的变换(缩放、旋转、平移等)。

在状态中,我们使用关键帧来跨时间操纵值。这就是您在 Storyboards 中实现动画的方式。如果只设置一个时间为 0 的 KeyFrame,它将显示为类似于使用 VisualState.Setters 更改属性机制的即时更改。

在 Collapsed 状态下,我们将 Grid 的不透明度和 Y 缩放比例从 1 更改为 0。这给出了显示内容折叠到标题中的动画。正如您从关键帧中看到的那样,我们将两个属性的动画错开,以便内容在完成对比例的操纵之前淡出。

在 Visible 状态下,我们通过在相同的时间内将不透明度和 Y 缩放比例从 0 更改为 1 来反转 Collapsed 状态。

尝试将这些加载到您的控件中并在 Blend 中使用它们。这是一个很好的起点,因为我很快就把它放在了一起。

您可以在此处找到有关使用 Blend 制作 Storyboard的更多信息:https://blogs.msdn.microsoft.com/avtarsohi/2016/02/16/understand-storyboard-concept-in-xaml-using-blend-2015/

关于xaml - 如何使用视觉状态为 UWP 中控件的可见性设置动画?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40704459/

相关文章:

c# - 当 CanExecute 为 false 时,带有启用主按钮的 uwp MVVM ContentDialog

uwp - 禁用 UWP 应用的缩放

java - 我如何模仿 Lollipop ( Material 设计)按钮动画?

WPF XAML 动画当绑定(bind) bool 值变为假时如何停止它?

c++ - 由于 WINAPI_PARTITION_DESKTOP block ,无法在 UWP 应用程序中使用 winscard.h

c# - 为什么 "TextWrapping"在插入TextBox时自动添加到XAML

javascript - 同一对象上不同动画的单独属性

WPF工具包图表: Customize datapoint label

c# - 访问 HubSection 内的数据

c# - 如何在wpf中使按钮和背景闪烁