0530VisualStateManager 动画

https://docs.microsoft.com/zh-cn/dotnet/api/system.windows.media.animation.storyboard?view=netframework-4.8

https://docs.microsoft.com/zh-cn/dotnet/api/system.windows.media.animation.doubleanimation?view=netframework-4.8

https://docs.microsoft.com/zh-cn/dotnet/api/xamarin.forms.animation?view=xamarin-forms

 

 

要使用 VisualStateManager,需要定义 VisualState;在 VisualState 中定义控件的不同的状态以及每种状态下的样式,然后,在代码中合适的地方,我们可以使用 VisusalStateManager 类的 GoToState 来切换到对应的状态,从而实现样式的切换。

  1. VisualState: 视图状态(Visual States)表示控件在一个特殊的逻辑状态下的样式、外观;
  2. VisualStateGroup: 状态组由相互排斥的状态组成,状态组与状态组并不互斥;
  3. VisualTransition: 视图转变 (Visual Transitions) 代表控件从一个视图状态向另一个状态转换时的过渡;
  4. VisualStateManager: 由它负责在代码中来切换到不同的状态;

每个 VisualState 都属于一个状态组 (VisualStateGroup),也即一个 VisualStateGroup 中可以定义多个 VisualState;并且,我们也可以定义多个 VisualStateGroup;需要再次强调的是:同一个 VisualStateGroup 中 VisualState 是互斥的,而不同的 VisualStateGroup 中的 VisualState 是在同一时刻是可以共存的。以 Button 为例:

技术分享图片

 

我们看到,在它里面,定义了三个 VisualStateGroup,分别是 CommonStates(正常状态)、FocusStates(焦点状态)、ValidationStates(验证状态),而每个 VisualStateGroup 下又有若干个 VisualState。在 CommonStates 中,按钮可以是 Normal 、MouseOver 或 Pressed(只能是三者之一),但它却可以结合其它 VisualStateGroup 中的 VisualState 来显示,如按钮具有焦点时且鼠标移动到其上,这就结合了 MouseOver 与 Focused 两种状态。以下它的部分代码:

<ControlTemplate TargetType="Button">
    <Grid>
        <VisualStateManager.VisualStateGroups>
            <VisualStateGroup x:Name="CommonStates">
                <VisualStateGroup.Transitions>
                    <VisualTransition GeneratedDuration="0:0:1" To="MouseOver" />
                    <VisualTransition GeneratedDuration="0:0:1" To="Pressed" />
                    <VisualTransition GeneratedDuration="0:0:1" To="Normal" />
                </VisualStateGroup.Transitions>
                <VisualState x:Name="Normal" />
                <VisualState x:Name="MouseOver">
                    <Storyboard>
                        <ColorAnimation
                            Storyboard.TargetName="BackgroundBorder"
                            Storyboard.TargetProperty="Background.(SolidColorBrush.Color)"
                            To="#A1D6FC"
                            Duration="0" />
                    </Storyboard>
                </VisualState>
                <VisualState x:Name="Pressed">
                    <Storyboard>
                        <ColorAnimation
                            Storyboard.TargetName="BackgroundBorder"
                            Storyboard.TargetProperty="Background.(SolidColorBrush.Color)"
                            To="#FCA1A1"
                            Duration="0" />
                    </Storyboard>
                </VisualState>
            </VisualStateGroup>
        </VisualStateManager.VisualStateGroups>
        <Border
            x:Name="BackgroundBorder"
            Background="{TemplateBinding Background}"
            BorderBrush="{TemplateBinding BorderBrush}"
            BorderThickness="{TemplateBinding BorderThickness}"
            SnapsToDevicePixels="true" />
        <ContentPresenter
            Margin="{TemplateBinding Padding}"
            HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
            VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
            Focusable="False"
            RecognizesAccessKey="True"
            SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
    </Grid>
</ControlTemplate>

在自定义控件的开发过程中,我们也可以采用同样的原则,即在 XAML 中定义 VisualStateGroup、VisualState 以及 VisualTransition(可选),由借助于 VisualStateManager 来实现切换。以下是一个带水印功能的 TextBox 中 VisualStates 的定义:

<VisualStateManager.VisualStateGroups>
   <VisualStateGroup x:Name="WatermarkGroup">
       <VisualStateGroup.Transitions>
           <VisualTransition From="ShowWatermarkState" To="HideWatermarkState">
              <Storyboard>
                 <DoubleAnimation Storyboard.TargetName="PART_Watermark"
                                  Storyboard.TargetProperty="Opacity" From="1"
                                  To="0" Duration="0:0:2" />
               </Storyboard>                                        
            </VisualTransition>
            <VisualTransition From="HideWatermarkState" To="ShowWatermarkState">
               <Storyboard>
                  <DoubleAnimation Storyboard.TargetName="PART_Watermark"
                                   Storyboard.TargetProperty="Opacity" From="0"
                                   To="1" Duration="0:0:2" />
               </Storyboard>
            </VisualTransition>
         </VisualStateGroup.Transitions>
         <VisualState x:Name="ShowWatermarkState">
            <Storyboard>
               <ObjectAnimationUsingKeyFrames Duration="0:0:0"
                             Storyboard.TargetName="PART_Watermark"
                             Storyboard.TargetProperty="(UIElement.Visibility)">
                  <DiscreteObjectKeyFrame KeyTime="0:0:0"
                             Value="{x:Static Visibility.Visible}"/>
               </ObjectAnimationUsingKeyFrames>
            </Storyboard>
         </VisualState>
         <VisualState x:Name="HideWatermarkState">
            <Storyboard>
               <ObjectAnimationUsingKeyFrames Duration="0:0:0"
                             Storyboard.TargetName="PART_Watermark"
                             Storyboard.TargetProperty="(UIElement.Visibility)">
                   <DiscreteObjectKeyFrame KeyTime="0:0:0"
                             Value="{x:Static Visibility.Collapsed}"/>
               </ObjectAnimationUsingKeyFrames>
            </Storyboard>
        </VisualState>                                
    </VisualStateGroup>
</VisualStateManager.VisualStateGroups>

可以看出,它定义了 WatermarkGroup 组,并在其中定义了 ShowWatermarkState 和 HideWatermarkState 两个 VisualState,并且,通过定义的 VisualTransition 能够实现在这两种状态下切换时,水印文本会有淡入、淡出的效果。

最后,在代码中,调用  VisualStateManager.GoToState 方法来切换到合适的状态即可:

private void UpdateState()
{
   bool textExists = Text.Length > 0;
   var watermark = GetTemplateChild("PART_Watermark") as FrameworkElement;
   var state = textExists || IsFocused ? "HideWatermarkState" : "ShowWatermarkState";
 
   VisualStateManager.GoToState(this, state, true);
}
 
protected override void OnGotFocus(RoutedEventArgs e)
{
   base.OnGotFocus(e);
   UpdateState();
}
 
protected override void OnLostFocus(RoutedEventArgs e)
{
   base.OnLostFocus(e);
   UpdateState();
}

https://blog.csdn.net/weixin_44138053/article/details/86523833

ContentPresenter   模板化视图的布局管理器。

Content

获取或设置使用 ContentPresenter 管理其布局的视图。

 

QuarticEase  一个缓动函数,该函数使用公式 f(t) = t4 创建加速和/或减速的动画。

<Rectangle Name="myRectangle" Width="200" Height="30" Fill="Blue">
    <Rectangle.Triggers>
        <EventTrigger RoutedEvent="Rectangle.MouseDown">
            <BeginStoryboard>
                <Storyboard>
                    <DoubleAnimation From="30" To="200" Duration="00:00:3" 
                     Storyboard.TargetName="myRectangle" 
                     Storyboard.TargetProperty="Height">
                        <DoubleAnimation.EasingFunction>
                            <QuarticEase EasingMode="EaseOut"/>
                        </DoubleAnimation.EasingFunction>
                    </DoubleAnimation>
                </Storyboard>
            </BeginStoryboard>
        </EventTrigger>
    </Rectangle.Triggers>

</Rectangle>

Animation  封装动画,此函数集合在用户可察觉的时间段内修改属性。

DoubleAnimation类创建两个目标值之间的转换。 若要设置其目标值,使用其From, To,和By属性。 下表总结了如何From, To,和By属性可能会一起使用或单独来确定动画的目标值。

指定的属性产生的行为
From从指定的值的动画From属性进行动画处理的属性的基值或前一个动画的输出值,具体取决于前一个动画的配置方式。
From 和 To从指定的值的动画From属性设置为指定的值To属性。
From 和 By从指定的值的动画From之和指定的值的属性FromBy属性。
To动画继续处理从经过动画处理的属性的基值或前一个动画的输出值与指定的值To属性。
By动画从要进行动画处理的属性的基值或前一个动画的输出值和指定的值的总和值By属性。

 

EasingFunction 获取或设置应用于此动画的缓动函数。

Duration

获取或设置此时间线播放的时间长度,而不是计数重复。(Inherited from Timeline)

EasingFunction

获取或设置应用于此动画的缓动函数。

Storyboard.TargetName 获取或设置要进行动画处理的对象的名称。

注解

设置此属性是可选的。 如果TargetName未指定,情节提要的动画应用于下列情况之一:

如果使用子时间线上设置此属性,这些子时间线"继承"的父TargetName除非指定其自己。

使对象作为目标

当使用XAML,执行以下两个操作,以使对象可通过一个情节提要之一:

使用代码时,您使对象可通过使用RegisterName方法以将对象分配一个名称。

依赖项属性信息

  
标识符字段TargetNameProperty
元数据属性设置为 true

 

Storyboard.TargetProperty 标识 Target 附加属性。

 

https://docs.microsoft.com/zh-cn/dotnet/api/system.windows.dependencyproperty?view=netframework-4.8

DependencyProperty

表示可通过诸如样式、数据绑定、动画和继承等方法设置的属性。

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值