如何避免WPF Expander控件加载时自动播放展开动画?
问题:Expander默认展开时加载阶段自动播放动画的解决
假设有一个WPF控件,其Trigger的EnterAction/ExitActions中包含Storyboard。本文场景为基于IsExpanded属性实现展开/收起动画的Expander控件,点击时动画运行正常,但当默认设置IsExpanded="True"时,控件加载阶段会自动播放展开动画,这是需要解决的问题。
最初的思路是使用VisualState并扩展Expander控件,以避免加载时运行动画,代码如下:
public class MyExpander : Expander { static MyExpander() { DefaultStyleKeyProperty.OverrideMetadata(typeof(MyExpander), new FrameworkPropertyMetadata(typeof(MyExpander))); } public override void OnApplyTemplate() { VisualStateManager.GoToState(this, IsExpanded ? "Expanded" : "Collapsed", false); base.OnApplyTemplate(); } protected override void OnExpanded() { VisualStateManager.GoToState(this, "Expanded", IsLoaded && IsVisible); System.Diagnostics.Debug.WriteLine($"Expand? {IsLoaded} && {IsVisible}, {IsInitialized}"); base.OnExpanded(); } protected override void OnCollapsed() { VisualStateManager.GoToState(this, "Collapsed", IsLoaded && IsVisible); base.OnCollapsed(); } }
同时在第一个FrameworkElement(本文中为Border)的子级ControlTemplate中添加如下内容:
<VisualStateManager.VisualStateGroups> <VisualStateGroup x:Name="ExpansionStates"> <VisualStateGroup.Transitions> <VisualTransition From="Collapsed" To="Expanded"> <!--<VisualTransition.GeneratedEasingFunction> <CircleEase EasingMode="EaseInOut"/> </VisualTransition.GeneratedEasingFunction>--> </VisualTransition> <VisualTransition From="Expanded" To="Collapsed"> <!--<VisualTransition.GeneratedEasingFunction> <CircleEase EasingMode="EaseInOut"/> </VisualTransition.GeneratedEasingFunction>--> </VisualTransition> </VisualStateGroup.Transitions> <VisualState x:Name="Expanded"> <Storyboard x:Name="ExpandStoryboard"> <DoubleAnimation Storyboard.TargetName="PresenterScaleTransform" Storyboard.TargetProperty="ScaleY" Duration="0:0:0.2" To="1" BeginTime="0:0:0"> <DoubleAnimation.EasingFunction> <CircleEase EasingMode="EaseInOut"/> </DoubleAnimation.EasingFunction> </DoubleAnimation> <DoubleAnimation Storyboard.TargetName="ExpandSite" Storyboard.TargetProperty="Opacity" Duration="0:0:0.05" To="1" BeginTime="0:0:0.15"> <DoubleAnimation.EasingFunction> <CircleEase EasingMode="EaseInOut"/> </DoubleAnimation.EasingFunction> </DoubleAnimation> <DoubleAnimation Storyboard.TargetName="SymbolRotateTransform" Storyboard.TargetProperty="Angle" Duration="0:0:0.2" To="180" BeginTime="0:0:0.1"> <DoubleAnimation.EasingFunction> <CircleEase EasingMode="EaseIn"/> </DoubleAnimation.EasingFunction> </DoubleAnimation> <ObjectAnimationUsingKeyFrames BeginTime="0:00:00" Storyboard.TargetName="ExpandSite" Storyboard.TargetProperty="Visibility"> <DiscreteObjectKeyFrame Value="{x:Static Visibility.Visible}" KeyTime="0:0:0"/> </ObjectAnimationUsingKeyFrames> </Storyboard> </VisualState> <VisualState x:Name="Collapsed"> <Storyboard> <DoubleAnimation Storyboard.TargetName="PresenterScaleTransform" Storyboard.TargetProperty="ScaleY" Duration="0:0:0.2" To="0" BeginTime="0:0:0"> <DoubleAnimation.EasingFunction> <CircleEase EasingMode="EaseInOut"/> </DoubleAnimation.EasingFunction> </DoubleAnimation> <DoubleAnimation Storyboard.TargetName="ExpandSite" Storyboard.TargetProperty="Opacity" Duration="0:0:0.1" To="0" BeginTime="0:0:0"> <DoubleAnimation.EasingFunction> <CircleEase EasingMode="EaseInOut"/> </DoubleAnimation.EasingFunction> </DoubleAnimation> <DoubleAnimation Storyboard.TargetName="SymbolRotateTransform" Storyboard.TargetProperty="Angle" Duration="0:0:0.2" To="0" BeginTime="0:0:0.1"> <DoubleAnimation.EasingFunction> <CircleEase EasingMode="EaseIn"/> </DoubleAnimation.EasingFunction> </DoubleAnimation> <ObjectAnimationUsingKeyFrames BeginTime="0:00:00" Storyboard.TargetName="ExpandSite" Storyboard.TargetProperty="Visibility"> <DiscreteObjectKeyFrame Value="{x:Static Visibility.Collapsed}" KeyTime="0:0:0.2"/> </ObjectAnimationUsingKeyFrames> </Storyboard> </VisualState> </VisualStateGroup> </VisualStateManager.VisualStateGroups>
尝试调整VisualTransition的配置,但效果反而变差。当前配置下点击时动画运行正常,但仍无法阻止加载阶段的动画播放。
内容的提问来源于stack exchange,提问作者Nicke Manarin
相关产品推荐
相关产品推荐

