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