今天一位收到网友求助:
"你好!我想向你请教关于动画的问题:比如,一个Page分为上、下l两块,我想通过动画实现分别隐藏某块的内容,当我触发一个按钮的Click事件时,实现隐藏上面的面板,同时下的面板就要延伸并占据上面面板的空间,这个过程到好实现,问题是我如果第二次触发这个按钮的Click事件时,怎么才能让上面的面板出现(恢复原始大小)并且下面的面板的大小也回到原始大小"
对于这个问题,有一个很好的解决方法是,将两个面板放到Grid中,并让GridLength类型支持动画,就像Double类型有着对应的DoubleAnimation一样.这样就将网友的问题转化为:上面的面板所在行对应RowDefinition的高度由0.5变为0,再由0变为0.5(单位GridUnitType.Star)
以下是GridLengthAnimation类的完整代码,你可以使用她就像使用DoubleAnimaion一样.
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Media.Animation;
using System.Windows;
using System.Diagnostics;

namespace GridAnimationDemo


{
internal
class GridLengthAnimation : AnimationTimeline

{
public
static
readonly DependencyProperty FromProperty;
public
static
readonly DependencyProperty ToProperty;

static GridLengthAnimation()

{
FromProperty = DependencyProperty.Register("From", typeof(GridLength),
typeof(GridLengthAnimation));

ToProperty = DependencyProperty.Register("To", typeof(GridLength),
typeof(GridLengthAnimation));
}

public
override Type TargetPropertyType

{
get

{
return
typeof(GridLength);
}
}

protected
override System.Windows.Freezable CreateInstanceCore()

{
return
new GridLengthAnimation();
}

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, GridUnitType.Star);
}
else
return
new GridLength(animationClock.CurrentProgress.Value * (toVal - fromVal) + fromVal, GridUnitType.Star);
}

public GridLength From

{
get

{
return (GridLength)GetValue(GridLengthAnimation.FromProperty);
}
set

{
SetValue(GridLengthAnimation.FromProperty, value);
}
}

public GridLength To

{
get

{
return (GridLength)GetValue(GridLengthAnimation.ToProperty);
}
set

{
SetValue(GridLengthAnimation.ToProperty, value);
}
}

}
}

下载Demo
"你好!我想向你请教关于动画的问题:比如,一个Page分为上、下l两块,我想通过动画实现分别隐藏某块的内容,当我触发一个按钮的Click事件时,实现隐藏上面的面板,同时下的面板就要延伸并占据上面面板的空间,这个过程到好实现,问题是我如果第二次触发这个按钮的Click事件时,怎么才能让上面的面板出现(恢复原始大小)并且下面的面板的大小也回到原始大小"
对于这个问题,有一个很好的解决方法是,将两个面板放到Grid中,并让GridLength类型支持动画,就像Double类型有着对应的DoubleAnimation一样.这样就将网友的问题转化为:上面的面板所在行对应RowDefinition的高度由0.5变为0,再由0变为0.5(单位GridUnitType.Star)
以下是GridLengthAnimation类的完整代码,你可以使用她就像使用DoubleAnimaion一样.
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Media.Animation;
using System.Windows;
using System.Diagnostics;
namespace GridAnimationDemo

{
internalclass GridLengthAnimation : AnimationTimeline

{
publicstatic
readonly DependencyProperty FromProperty;
publicstatic
readonly DependencyProperty ToProperty;

static GridLengthAnimation()
{
FromProperty = DependencyProperty.Register("From", typeof(GridLength),
typeof(GridLengthAnimation));
ToProperty = DependencyProperty.Register("To", typeof(GridLength),
typeof(GridLengthAnimation));
}
publicoverride Type TargetPropertyType

{
get 
{
returntypeof(GridLength);
}
}
protectedoverride System.Windows.Freezable CreateInstanceCore()

{
returnnew GridLengthAnimation();
}
publicoverride
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)
{
returnnew GridLength((1
- animationClock.CurrentProgress.Value) * (fromVal - toVal) + toVal, GridUnitType.Star);
}
else
returnnew GridLength(animationClock.CurrentProgress.Value * (toVal - fromVal) + fromVal, GridUnitType.Star);
}

public GridLength From
{
get
{
return (GridLength)GetValue(GridLengthAnimation.FromProperty);
}
set
{
SetValue(GridLengthAnimation.FromProperty, value);
}
}
public GridLength To
{
get
{
return (GridLength)GetValue(GridLengthAnimation.ToProperty);
}
set
{
SetValue(GridLengthAnimation.ToProperty, value);
}
}

}
}
下载Demo

添加至收藏夹