🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
今天, 我给大家讲解如何用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](http://msdn.microsoft.com/zh-cn/library/system.windows.freezable.createinstancecore%28VS.90%29.aspx), 代码如下: ~~~ protected override System.Windows.Freezable CreateInstanceCore() { return new GridLengthAnimation(); } ~~~ 2. 重载[GetCurrentValue](http://msdn.microsoft.com/zh-cn/library/system.windows.media.animation.animationtimeline.getcurrentvalue%28VS.90%29.aspx)以返回动画的当前值, 代码如下: ~~~ 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); } else return new GridLength(animationClock.CurrentProgress.Value * (toVal - fromVal) + fromVal, ((GridLength)GetValue(GridLengthAnimation.ToProperty)).GridUnitType); } ~~~ 3. 重写[TargetPropertyType](http://msdn.microsoft.com/zh-cn/library/system.windows.media.animation.animationtimeline.targetpropertytype%28VS.90%29.aspx) 属性以指示相应的动画所生成输出的[Type](http://msdn.microsoft.com/zh-cn/library/system.type%28VS.90%29.aspx), 代码如何: ~~~ 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](http://dldx.csdn.net/fd.php?i=469722551228511&s=59ce5766f682bd855d87ec381d1c2945) (如果打不开, 请到我的csdn的资源里下载, 资源分是0)