创建组件用户控件,将组件的各部分 “零件”(图片) 拼装在一起,形成组件的默认状态:
需要平移则加上 TranslateTransform,需要旋转则加上 RotateTransform,并起好名称:
可改变一下数值看看效果:
在组件布局代码的外面放置 VisualStateManager.VisualStateGroups,一个 VisualStateGroup 代表一组互斥的视觉状态。此处定义了三个视觉状态(Normal、LeftExtend、RightExtend),共同组成了 “手臂状态” 这个视觉状态组:
三个视觉状态分别设置了对应变换的 X 值:
示例代码:
<!-- 转换动画 -->
<VisualStateGroup Name="ArmState">
<VisualState Name="Normal">
<Storyboard FillBehavior="HoldEnd" SpeedRatio="1">
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="topTranslateTransform" Storyboard.TargetProperty="X">
<LinearDoubleKeyFrame KeyTime="0:0:0.5" Value="0"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState Name="LeftExtend">
<Storyboard FillBehavior="HoldEnd">
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="topTranslateTransform" Storyboard.TargetProperty="X">
<LinearDoubleKeyFrame KeyTime="0:0:0.5" Value="-30"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState Name="RightExtend">
<Storyboard FillBehavior="HoldEnd">
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="topTranslateTransform" Storyboard.TargetProperty="X">
<LinearDoubleKeyFrame KeyTime="0:0:0.5" Value="30"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
首先定义一个相应的视觉状态枚举,Key 和之前定义的视觉状态名称相同,方便之后使用:
然后在用户控件后台代码中新增一个依赖属性,用于给外界绑定相应的视觉状态,并在变动方法中使用 VisualStateManager.GoToState
方法进行状态的切换,其中一个视觉状态名称的参数就使用了创建的枚举的字符串形式:
同时重写 OnApplyTemplate () 方法,在其中将相关视觉状态切换为初始值:
注意:之前定义 VisualStateGroup 时的名称 “ArmState”,可能会和依赖属性 ArmState 冲突,建议两者不同名。这里我将依赖属性重命名为 FtrArmState。
首先给新建的用户控件创建一个对应的 ViewModel 以便使用,在其中添加一个绑定属性,以及一个测试用的命令:
将这个 VM 在要使用的界面的 VM 中进行声明和创建,然后在前台绑定即可:
效果(动图):
这个就是控件内部的动画,如果还需要控件整体的平移等动画,可以将其当作一个零件,然后在外部再按照本文的方法制作动画,原理是一样的。
以下为正确位置:
如果放在图 1 的 “机械运动区” 的 Canvas 中,则 VisualStateManager.GoToState 方法会返回 false。
下面的放置方式也是不行的:
也就是说控件的布局代码和视觉状态组需要并列地放在同一个面板 (UserControl 不行) 中。
原创文章,转载请注明: 转载自 独立观察员 (dlgcy.com)