WPF: 一个可以用StoryBoard动态改变Grid行宽/列高的类

2016-08-20 10:37:57来源:http://muzizongheng.blog.51cto.com/856912/1333124作者:muzizongheng人点击


今天, 我给大家讲解如何用C#动态改变grid容器的行宽或者列高.WPF的Storyboard真的很强大, 尤其是和blend 3配和后就更容易了, 但是呢仔细看下Grid的width/height的数据类型是GridLength, 也就是说不是普通的Int, Double, Boolean, Char, Byte, Color, Point类型, 而wpf也没有给我们提供一个GridLength的动画类.GridLength是一个struct.

(一) 创建一个支持GridLength类型的动画类

我们新建一个继承AnimationTimeLine的类GridLengthAnimation, 我们简单实现2个依赖属性"From", "To".代码如何:

internal class GridLengthAnimation : AnimationTimeline{static GridLengthAnimation(){FromProperty = DependencyProperty.Register("From", typeof(GridLength),typeof(GridLengthAnimation));ToProperty = DependencyProperty.Register("To", typeof(GridLength), typeof(GridLengthAnimation));}public static readonly DependencyProperty FromProperty;public GridLength From{get{return (GridLength)GetValue(GridLengthAnimation.FromProperty);}set{SetValue(GridLengthAnimation.FromProperty, value);}}public static readonly DependencyProperty ToProperty;public GridLength To{get{return (GridLength)GetValue(GridLengthAnimation.ToProperty);}set{SetValue(GridLengthAnimation.ToProperty, value);}}

接下来我们就来依次重载或者实现AnimationTimeLine类的成员,

1. 重载CreateInstanceCore, 代码如下:

protected override System.Windows.Freezable CreateInstanceCore(){return new GridLengthAnimation();}

2. 重载GetCurrentValue以返回动画的当前值, 代码如下:

public override object GetCurrentValue(object defaultOriginValue, object defaultDestinationValue, AnimationClock animationClock){double fromVal = ((GridLength)GetValue(GridLengthAnimation.FromProperty)).Value;double toVal = ((GridLength)GetValue(GridLengthAnimation.ToProperty)).Value;if (fromVal > toVal){return new GridLength((1 - animationClock.CurrentProgress.Value) * (fromVal - toVal) + toVal,((GridLength)GetValue(GridLengthAnimation.FromProperty)).GridUnitType);}elsereturn new GridLength(animationClock.CurrentProgress.Value * (toVal - fromVal) + fromVal,((GridLength)GetValue(GridLengthAnimation.ToProperty)).GridUnitType);}

3. 重写TargetPropertyType 属性以指示相应的动画所生成输出的Type, 代码如何:

public override Type TargetPropertyType{get {return typeof(GridLength);}}

ok, 通过上面的步骤我们已经写好了GridLengthAnimation类, 接下来就是如何使用此类.

(二)xaml使用此类, 代码如何:

<Window.Resources> <Storyboard x:Key="sbDock"><common:GridLengthAnimation BeginTime="00:00:00" Storyboard.TargetName="_cellLeft" Storyboard.TargetProperty="Width"></common:GridLengthAnimation></Storyboard></Window.Resources><Grid x:Name="LayoutRoot" Background="White"><Grid.RowDefinitions><RowDefinition/></Grid.RowDefinitions><Grid.ColumnDefinitions><ColumnDefinition x:Name="_cellLeft" Width="300"/><ColumnDefinition x:Name="_cellRight" Width="*"/></Grid.ColumnDefinitions></Grid>

(三)c#使用此类, 代码如下:

Storyboard sbDock = this.FindResource("sbDock") as Storyboard;if (sbDock != null){SplineDoubleKeyFrame sdKeyFrame1 = new SplineDoubleKeyFrame(TransformRadius, KeyTime.FromTimeSpan(TimeSpan.FromSeconds(1)));(sbDock.Children[0] as DoubleAnimationUsingKeyFrames).KeyFrames.Clear();(sbDock.Children[0] as DoubleAnimationUsingKeyFrames).KeyFrames.Add(sdKeyFrame1);(sbDock.Children[1] as GridLengthAnimation).From = new GridLength(300, GridUnitType.Pixel);(sbDock.Children[1] as GridLengthAnimation).To = new GridLength(0, GridUnitType.Pixel);sbDock.Begin();}

工程代码: GridLengthDemo.rar (如果打不开, 请到我的csdn的资源里下载, 资源分是0)


最新文章

123

最新摄影

微信扫一扫

第七城市微信公众平台