WPF 后台代码做 TranslateTransform 的动画
本文告诉大家,在后台代码,对 TranslateTransform 做动画的方法
今天小伙伴问我一个问题,说为什么相同的代码,如果设置到按钮上,是可以让按钮的某个属性变更,但是如果设置给 TranslateTransform 的 X 或 Y 就不会有任何值变更
在 WPF 中,通过 官方文档 里面的描述,对于 Freezable 类型的对象,如 SolidColorBrush 和 RotateTransform 和 GradientStop 等类型,都是不支持直接的动画,也就是如以下代码是不能触发动画
假定有 XAML 界面如下,期望在点击按钮时,修改按钮的 TranslateTransform 做动画
<Grid>
<Button x:Name="Button" HorizontalAlignment="Center" VerticalAlignment="Center" Content="按钮" Click="Button_OnClick">
<Button.RenderTransform>
<TranslateTransform x:Name="ButtonTranslateTransform"></TranslateTransform>
</Button.RenderTransform>
</Button>
</Grid>
如果直接对使用 Storyboard 的 SetTarget 方法给对象设置 DoubleAnimation 将会是无效的,也就是说如以下的代码做的 TranslateTransform 动画是无效的,没有反应的
private void Button_OnClick(object sender, RoutedEventArgs e)
{
var storyboard = new Storyboard();
var doubleAnimation = new DoubleAnimation();
Storyboard.SetTarget(doubleAnimation, ButtonTranslateTransform);
Storyboard.SetTargetProperty(doubleAnimation, new PropertyPath(TranslateTransform.XProperty));
doubleAnimation.To = 100;
doubleAnimation.Duration = new Duration(TimeSpan.FromSeconds(2));
storyboard.Children.Add(doubleAnimation);
storyboard.Begin();
}
如果想要给 Freezable 类型的对象做动画,可以通过间接的方法,也就是通过 Freezable 类型的对象所在的元素,使用点的方式写出来具体的代码
private void Button_OnClick(object sender, RoutedEventArgs e)
{
var storyboard = new Storyboard();
var doubleAnimation = new DoubleAnimation();
Storyboard.SetTarget(doubleAnimation, Button);
Storyboard.SetTargetProperty(doubleAnimation, new PropertyPath("(UIElement.RenderTransform).(TranslateTransform.X)"));
doubleAnimation.To = 100;
doubleAnimation.Duration = new Duration(TimeSpan.FromSeconds(2));
storyboard.Children.Add(doubleAnimation);
storyboard.Begin();
}
写法就是通过某个元素的某个属性加上某个类型的某个属性。如上面代码使用的是 UIElement 的 RenderTransform 属性,这个属性的值的类型是 TranslateTransform 类型,设置这个类型的 X 属性
上面的 PropertyPath 有可以换成如下方式写
var propertyChain = new object[]
{
UIElement.RenderTransformProperty,
TranslateTransform.XProperty
};
Storyboard.SetTargetProperty(doubleAnimation, new PropertyPath("(0).(1)", propertyChain));
我更推荐使用这个写法,因为这样就不会写错命名
而如果只是为了修改 TranslateTransform 的 X 属性,最简单的写法就是通过 BeginAnimation 的方式,如下面代码
private void Button_OnClick(object sender, RoutedEventArgs e)
{
ButtonTranslateTransform.BeginAnimation(TranslateTransform.XProperty, new DoubleAnimation()
{
To = 100,
Duration = new Duration(TimeSpan.FromSeconds(1))
});
}
以上代码可以看到很清真
这里的 Duration 其实可以通过 TimeSpan 转换,而不需要创建 Duration 对象。然而在 WPF 依然定义 Duration 类的原因是为了支持 Duration.Automatic 和 Duration.Forever 特殊的定义
如果是需要有多个属性开始做动画,不想使用 BeginAnimation 的方式,可以通过在后台代码用 SetTargetName 的方法指定,如下面代码
private void Button_OnClick(object sender, RoutedEventArgs e)
{
var storyboard = new Storyboard();
var doubleAnimation = new DoubleAnimation();
Storyboard.SetTargetName(doubleAnimation, nameof(ButtonTranslateTransform));
Storyboard.SetTargetProperty(doubleAnimation, new PropertyPath(TranslateTransform.XProperty));
doubleAnimation.To = 100;
doubleAnimation.Duration = new Duration(TimeSpan.FromSeconds(2));
var storyboardName = "s" + storyboard.GetHashCode();
// 加入到字典,让 Storyboard 和 ButtonTranslateTransform 在相同的一个 NameScope 里
Resources.Add(storyboardName, storyboard);
storyboard.Children.Add(doubleAnimation);
storyboard.Begin();
}
在后台代码做动画,如果使用 SetTargetName 就需要让 Storyboard 和对应的元素在相同的一个 NameScope 里,不然将会提示 System.InvalidOperationException 不存在可解析名称“xx”的适用名称领域,如下面代码
System.InvalidOperationException:“不存在可解析名称“ButtonTranslateTransform”的适用名称领域。”
上面代码通过将动画加入到资源字典的方式,让动画和元素在相同的 NameScope 而让动画能找到元素。但是上面代码将会在资源字典加入一个 Storyboard 而没有释放,如果在你的实际代码,我推荐在动画完成之后,删除资源字典的动画
我特别翻了 WPF 编程宝典,发现宝典里面没有这部分知识,也就是没有告诉大家为什么直接给 TranslateTransform 的属性做动画将会失效。好在官方文档里面有说到这点
可以通过如下方式获取本文的源代码,先创建一个空文件夹,接着使用命令行 cd 命令进入此空文件夹,在命令行里面输入以下代码,即可获取到本文的代码
git init
git remote add origin https://gitee.com/lindexi/lindexi_gd.git
git pull origin 78f63c1c076065d1891559f5af2cb29f10a39f8b
以上使用的是 gitee 的源,如果 gitee 不能访问,请替换为 github 的源
git remote remove origin
git remote add origin https://github.com/lindexi/lindexi_gd.git
获取代码之后,进入 KayceefiwhearHaijanihukere 文件夹
Storyboards Overview - WPF .NET Framework
WPF 后台代码做 TranslateTransform 的动画的更多相关文章
- How do I duplicate a resource reference in code behind in WPF?如何在WPF后台代码中中复制引用的资源?
原文 https://stackoverflow.com/questions/28240528/how-do-i-duplicate-a-resource-reference-in-code-behi ...
- WPF后台代码实现TextBlock滚动条
方法一: 常规的WPF操作: <ScrollViewer Width=" VerticalScrollBarVisibility="Auto" Horizontal ...
- C# Wpf 后台代码设定UIElement的Canvas位置属性值
后台in-code设定元件UIElement的Canvas位置属性的两种方法: 1.UIElement.SetValue()方法 uiElement.SetValue(Canvas.TopProper ...
- 7.7 WPF后台代码绑定如果是属性,必须指定一下数据上下文才能实现,而函数(click)就不用
如: private bool _IsExportWithImage; /// <summary> /// 是否选择导出曲线图 /// </summary> public bo ...
- WPF MVVM 架构 Step By Step(4)(添加bindings - 完全去掉后台代码)
之前的改进已经挺棒的,但是我们现在知道了后台代码的问题,那是否可能把后台代码全部去除呢?这时候就该WPF binding 和 commands 来做的事情了. WPF就是以超吊的binding,com ...
- WPF后台动画DoubleAnimation讲解
WPF后台动画,使用DoubleAnimation做的. 1.移动动画 需要参数(目标点离最上边的位置,目标点离最左边的位置,元素名称) Image mImage = new Image(); Flo ...
- WPF内嵌代码和后台代码简单混合使用
下面实例展示了WPF内嵌代码和后台代码混合使用,一个简单基础的实例: xaml文件: <Window x:Class="WPF内嵌代码和后台代码混合使用.MainWindow" ...
- WPF MVVM 架构 Step By Step(3)(把后台代码移到一个类中)
我觉得大部分开发者应该已经知道怎么去解决这个问题.一般都是把后台代码(GLUE code)移动到一个类库.这个类库用来代表UI的属性和行为.任何代码当被移到一个类库中时都可以被编译成一个DLL,然后可 ...
- wpf 分别用 xaml 和后台代码实现 色彩渐变
xaml 方法: <Window x:Class="WpfApplication1.MainWindow" xmlns="http://schemas.micros ...
随机推荐
- 【JavaScript】Leetcode每日一题-组合总和4
[JavaScript]Leetcode每日一题-组合总和4 [题目描述] 给你一个由 不同 整数组成的数组 nums ,和一个目标整数 target .请你从 nums 中找出并返回总和为 targ ...
- [BUUCTF-Pwn]刷题记录1
[BUUCTF-Pwn]刷题记录1 力争从今天(2021.3.23)开始每日至少一道吧--在这里记录一些栈相关的题目. 最近更新(2021.5.8) 如果我的解题步骤中有不正确的理解或不恰当的表述,希 ...
- ConcurrentHashMap源码解读二
接下来就讲解put里面的三个方法,分别是 1.数组初始化方法initTable() 2.线程协助扩容方法helpTransfer() 3.计数方法addCount() 首先是数组初始化,再将源码之前, ...
- JVM内存溢出后服务还能运行吗
文章开篇问一个问题吧,一个java程序,如果其中一个线程发生了OOM,那进程中的其他线程还能运行吗? 接下来做实验,看看JVM的六种OOM之后程序还能不能访问. 在这里我用的是一个springboot ...
- rsync同步遇到的报错和解决办法
rsync同步遇到的报错和解决办法 科技小能手 2017-11-12 18:27:00 浏览1125 配置 code 同步 open stream file read 在同步的客户端操作: [ ...
- 攻防世界(十三)unserialize3
攻防世界系列 :unserialize3 1.打开题目,反序列化 2.代码审计 类xctf被调用时_weakeup()函数会被自动执行,但当序列化字符串中属性值个数大于属性个数,就会导致反序列化异常, ...
- IT菜鸟之计算机软件
一.计算机系统的分类 32位操作系统:32/u:更省资源:支持4G以内的内存 64位操作系统:64/u:速度更快:支持4G以外的内存 内存单位:B KB MB GB TB 换算:1024(2的10次 ...
- 分布式存储ceph---ceph概念及原理(1)
一.Ceph简介: Ceph是一种为优秀的性能.可靠性和可扩展性而设计的统一的.分布式文件系统.ceph 的统一体现在可以提供文件系统.块存储和对象存储,分布式体现在可以动态扩展.在国内一些公司的云环 ...
- kvm虚拟机迁移(6)
一.迁移简介 迁移: 系统的迁移是指把源主机上的操作系统和应用程序移动到目的主机,并且能够在目的主机上正常运行. 在没有虚拟机的时代,物理机之间的迁移依靠的是系统备份和恢复技术.在源主机上实 ...
- IDEA 打包和导入 Jar 包
Jar 包介绍 Jar 包 ( Java Archive,Java 归档文件) 是与平台无关的压缩文件格式,它允许将多个 Java 源文件编译生成的 class 文件(即字节码文件)打包成一个压缩文件 ...