先看一段代码,本文所有的例子,都是在这段代码的基础上进行的.
一个矩形rec,放到布局容器内,这个矩形就是被动画控制的对象,一个double类型的动画.
以前我后台写动画,都是通过先给对象注册名称,通过名称,把对象(Rectangle)和动画(DoubleAnimation)通过Storyboard.SetTargetName()关联到故事版(Storyboard).
例:给矩形加一个TranslateTransform,通过控制X属性,使矩形水平位移
这种方式,动画可以动起来.注意最后的Begin()方法,一定要传一个参数,可以是window(this),可以是布局容器Layout,也可以是矩形自身rec.总之一定要传一个参数,不然动画动不起来.
至于为什么,不知道.去查阅MSDN,无果. https://msdn.microsoft.com/zh-cn/library/cc190590(v=vs.95).aspx
还有一个问题是,如果想对动画进行后续操作,要传入第二个参数为True.(感谢@ligl007的提醒) sb.Begin(this, true),否则对动画进行的暂定,继续,停止等后续操作全部无效.调用移除方法Remove(),也不能触发Completed事件.
为了解决这个问题,做了几种情况的总结.
最终的结果都是使用Storyboard.SetTarget()方法代替Storyboard.SetTargetName(),这样能避免给对象注册无意义的Name,Begin()方法不传参数.这样就能进行暂定,继续,停止等后续操作了,调用移除方法Remove()时,能够触发Completed事件.
1.改变对象的值类型的依赖属性,如Width,Height等,直接把注册名称换成注册对象就可以,其他没什么变化
2.改变对象的引用类型的依赖属性,如转换RenderTransform等,对象要注册矩形rec而不是TranslateTransform,属性路径要按属性路径语法写,而不是new PropertyPath(TranslateTransform.XProperty).可以理解成矩形并没有TranslateTransform.XProperty属性.
属性路径语法请参考: https://msdn.microsoft.com/zh-cn/library/cc645024(v=vs.95).aspx
3.同2,只不过把转换换成了转换组,重点看属性路径语法,这个语法MSDN并没有提到,我是通过试错,试出来的,这个语法很严格,多个或少个括号,括号换个位置,都不行
完毕,贴出可以复制的代码吧
1 private Storyboard m_sb; 2 3 private void Window_Loaded(object sender, RoutedEventArgs e) 4 { 5 m_sb = Test(); 6 } 7 8 private void Button_Click(object sender, RoutedEventArgs e) 9 { 10 m_sb.Remove(this); 11 } 12 13 private Storyboard Test() 14 { 15 Rectangle rec = new Rectangle() { Width = 50, Height = 50 }; 16 rec.Fill = new SolidColorBrush(Color.FromRgb(255, 0, 0)); 17 Layout.Children.Add(rec); 18 19 DoubleAnimation da = new DoubleAnimation(); 20 da.Duration = new Duration(TimeSpan.FromSeconds(2)); 21 da.From = 200; 22 da.To = 50; 23 da.RepeatBehavior = RepeatBehavior.Forever; 24 da.AutoReverse = true; 25 26 //注册名称方式 27 //可以动 但Storyboard的Begin()要传一个参数,可以传this或父级 如需做后续操作 需要把Begin()的第二个参数设置为true 28 TranslateTransform tTf = new TranslateTransform(); 29 rec.RenderTransform = tTf; 30 //名称不能以数字开头,不能包含"-" 31 string name = "tTf" + Guid.NewGuid().ToString().Replace("-", ""); 32 this.RegisterName(name, tTf); 33 Storyboard.SetTargetName(da, name); 34 Storyboard.SetTargetProperty(da, new PropertyPath(TranslateTransform.XProperty)); 35 Storyboard sb = new Storyboard(); 36 sb.Completed += sb_Completed; 37 sb.Children.Add(da); 38 sb.Begin(this, true); 39 return sb; 40 41 ////1.改变对象的值类型的依赖属性 42 ////有效 43 //Storyboard.SetTarget(da, rec);//通过名称注册换成通过对象注册 44 //Storyboard.SetTargetProperty(da, new PropertyPath(Rectangle.WidthProperty)); 45 ////Storyboard 46 //Storyboard sb = new Storyboard(); 47 //sb.Completed += sb_Completed; 48 //sb.Children.Add(da); 49 //sb.Begin(); 50 //return sb; 51 52 ////2.改变对象的引用类型的依赖属性 53 //TranslateTransform tTf = new TranslateTransform(); 54 //rec.RenderTransform = tTf; 55 //////无效 56 ////Storyboard.SetTarget(da, tTf);//转换 57 ////Storyboard.SetTargetProperty(da, new PropertyPath(TranslateTransform.XProperty));//不按属性路径语法 58 //////无效 59 ////Storyboard.SetTarget(da, rec);//矩形 60 ////Storyboard.SetTargetProperty(da, new PropertyPath(TranslateTransform.XProperty));//不按属性路径语法 61 ////有效 62 //Storyboard.SetTarget(da, rec);//矩形 63 //Storyboard.SetTargetProperty(da, new PropertyPath("(Rectangle.RenderTransform).(TranslateTransform.X)"));//按属性路径语法 64 ////Storyboard 65 //Storyboard sb = new Storyboard(); 66 //sb.Completed += sb_Completed; 67 //sb.Children.Add(da); 68 //sb.Begin(); 69 //return sb; 70 71 ////3.转换组,属性路径语法 72 //TranslateTransform tTf = new TranslateTransform(); 73 //ScaleTransform sTf = new ScaleTransform(); 74 //TransformGroup tfg = new TransformGroup(); 75 //tfg.Children.Add(tTf); 76 //tfg.Children.Add(sTf); 77 //rec.RenderTransform = tfg; 78 ////有效 79 //Storyboard.SetTarget(da, rec);//矩形 80 //Storyboard.SetTargetProperty(da, new PropertyPath("(Rectangle.RenderTransform).Children[0].(TranslateTransform.X)"));//按属性路径语法 81 ////Storyboard 82 //Storyboard sb = new Storyboard(); 83 //sb.Completed += sb_Completed; 84 //sb.Children.Add(da); 85 //sb.Begin(); 86 //return sb; 87 } 88 89 void sb_Completed(object sender, EventArgs e) 90 { 91 92 }
原理依然不清楚,如有大神知道,望指点
如果感觉此文对你有帮助,请点击"推荐"
推荐一个不错的Blend,Wpf,sl交流群
群号码:152049269
欢迎大神,萌新踊跃加入,交流探讨,共同进步!
- 2楼ligl007
- 详见msdn 代码示例,https://msdn.microsoft.com/zh-cn/library/ms742868(v=vs.100).aspx
- Re: 普通的地球人
- @ligl007,多谢 按照你给的方法 已解决问题
- 1楼ligl007
- 调用使用两个参数方式 myStoryboard.Begin(this, true);,Stop、Pause、SkipToFill、SetSpeedRatio 下面的方法才能有作用。