WPF 机械类组件动画制作流程简述

WPF 机械类组件动画制作流程简述

WPF 机械类组件动画制作流程简述

独立观察员 2025 年 3 月 4 日

一、创建组件

创建组件用户控件,将组件的各部分 “零件”(图片) 拼装在一起,形成组件的默认状态:

getImage

 

二、给运动部分加上 RenderTransform

需要平移则加上 TranslateTransform,需要旋转则加上 RotateTransform,并起好名称:

getImage-1

 

可改变一下数值看看效果:

getImage-2

 

三、添加转换动画视觉状态

在组件布局代码的外面放置 VisualStateManager.VisualStateGroups,一个 VisualStateGroup 代表一组互斥的视觉状态。此处定义了三个视觉状态(Normal、LeftExtend、RightExtend),共同组成了 “手臂状态” 这个视觉状态组:

getImage-3

 

三个视觉状态分别设置了对应变换的 X 值:

getImage-4

 

示例代码:

<!-- 转换动画 -->
<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>

 

20250514 更新:动画简化

由于 VisualStateGroup 可不指定名称,Storyboard 的 FillBehavior 默认值就是 HoldEnd,SpeedRatio 默认值就是 1,简单的情况下 DoubleAnimationUsingKeyFrames 可换为 DoubleAnimation,所以视觉状态组可简化为如下所示:

a34ccdb3062a97b826edad9383ac72cf

 

文字版:

<VisualStateGroup>
                <VisualState Name="OpenUp">
                    <Storyboard>
                        <DoubleAnimation Storyboard.TargetName="rgdTranslate" Storyboard.TargetProperty="X" To="211" Duration="0:0:1"/>
                        <DoubleAnimation Storyboard.TargetName="rgdTranslate" Storyboard.TargetProperty="Y" To="33" Duration="0:0:1"/>
                    </Storyboard>
                </VisualState>
                <VisualState Name="OpenDown">
                    <Storyboard>
                        <DoubleAnimation Storyboard.TargetName="rgdTranslate" Storyboard.TargetProperty="X" To="211" Duration="0:0:1"/>
                        <DoubleAnimation Storyboard.TargetName="rgdTranslate" Storyboard.TargetProperty="Y" To="63" Duration="0:0:1"/>
                    </Storyboard>
                </VisualState>
</VisualStateGroup>

 

四、使用视觉状态

首先定义一个相应的视觉状态枚举,Key 和之前定义的视觉状态名称相同,方便之后使用:

getImage-5

 

然后在用户控件后台代码中新增一个依赖属性,用于给外界绑定相应的视觉状态,并在变动方法中使用 VisualStateManager.GoToState  方法进行状态的切换,其中一个视觉状态名称的参数就使用了创建的枚举的字符串形式:

getImage-6

 

同时重写 OnApplyTemplate () 方法,在其中将相关视觉状态切换为初始值:

getImage-7

 

注意:之前定义 VisualStateGroup 时的名称 “ArmState”,可能会和依赖属性 ArmState 冲突,建议两者不同名。这里我将依赖属性重命名为 FtrArmState。

 

20250310 更新:

VisualStateGroup 可不加名称:

getImage-17

 

五、外部使用

首先给新建的用户控件创建一个对应的 ViewModel 以便使用,在其中添加一个绑定属性,以及一个测试用的命令:

getImage-8

 

将这个 VM 在要使用的界面的 VM 中进行声明和创建,然后在前台绑定即可:

getImage-9

效果(动图):

getImage-10

 

这个就是控件内部的动画,如果还需要控件整体的平移等动画,可以将其当作一个零件,然后在外部再按照本文的方法制作动画,原理是一样的。

 

20250305 更新:外部绑定 DataContext

用户控件的 Xaml 中通过样式来设置相关状态的绑定:

getImage-15

 

使用之处给 DataContext 绑定 ViewModel 即可:

getImage-14

 

20250310 更新:外部整体指定动画注意事项

直接给用户控件指定变换会报错:

getImage-16

 

需要再包一层来指定变换:

getImage-18

 

20250514 更新:动画部分直接放在页面中

如果动画部分没有放在单独的用户控件中,而是直接放在某个页面(当然可能也是一个用户控件)中:

5c0b2a25b09dc40b6c6084f4550a6eb7

 

也就是说,它用的依赖属性和绑定的值都是属于页面的(后台和VM中),那么 VisualStateManager.GoToState 也会返回 false,此时可换用 VisualStateManager.GoToElementState 方法,并将第一个参数指定为 包含 VisualStateManager 的根元素(如上图中的 visualStateRoot):

3e1b217e9150ebf83982b73b0f41dc50

 

也就是说,GoToState 方法适用于从控件内部切换状态,GoToElementState 方法适用于从控件外部切换状态(参考:微软文档)。

 

六、关于 VisualStateGroups 的放置位置

以下为正确位置:

getImage-11

getImage-12

 

如果放在图 1 的 “机械运动区” 的 Canvas 中,则 VisualStateManager.GoToState 方法会返回 false。

下面的放置方式也是不行的:

getImage-13

也就是说控件的布局代码和视觉状态组需要并列地放在同一个面板 (UserControl 不行) 中。

 

 

原创文章,转载请注明: 转载自 独立观察员(dlgcy.com)

本文链接地址: [WPF 机械类组件动画制作流程简述](https://dlgcy.com/wpf-create-machine-animation-simple-steps/)

关注微信公众号 独立观察员博客(DLGCY_BLOG) 第一时间获取最新文章

%title插图%num

目前为止有一条评论

Jayme Lesbisch 发布于03:11 - 2025年8月5日

You’re so interesting! I do not believe I have read anything like this before.

So wonderful to discover someone with some original thoughts on this issue.
Seriously.. thank you for starting this up.
This site is one thing that is required on the web, someone with a little originality!
Lesbisch

发表评论