Wpf 将动画应用于网格列后GridSplitter不工作

Wpf 将动画应用于网格列后GridSplitter不工作,wpf,animation,gridsplitter,Wpf,Animation,Gridsplitter,我是wpf的初学者,今天我遇到了一个奇怪的问题,如果我向网格列添加动画,gridsplitter将停止工作,下面是代码片段,这是一个没有意义但非常简单的测试代码,它除了鼠标进入右列外什么都不做,它的宽度将从15扩展到100 <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Name="c1"/> <ColumnDefinition Name="c2" Wid

我是wpf的初学者,今天我遇到了一个奇怪的问题,如果我向网格列添加动画,gridsplitter将停止工作,下面是代码片段,这是一个没有意义但非常简单的测试代码,它除了鼠标进入右列外什么都不做,它的宽度将从15扩展到100

    <Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Name="c1"/>
        <ColumnDefinition Name="c2" Width="15" MinWidth="15"/>
    </Grid.ColumnDefinitions>
    <Border Grid.Column="0" Background="Gray"></Border>
    <GridSplitter Width="8" Background="Yellow"></GridSplitter>
    <Border Grid.Column="1" Background="Silver" Name="bdRight" MouseEnter="bdRight_MouseEnter"></Border>
</Grid>
这是GridLengthAnimation,当我发现DoubleAnimation不能用于网格列的宽度时,我从互联网上得到它

public class GridLengthAnimation : AnimationTimeline
{
    public static readonly DependencyProperty FromProperty;
    public static readonly DependencyProperty ToProperty;
    public static readonly DependencyProperty EasingFunctionProperty;

    static GridLengthAnimation()
    {
        FromProperty = DependencyProperty.Register("From", typeof(GridLength), typeof(GridLengthAnimation));
        ToProperty = DependencyProperty.Register("To", typeof(GridLength), typeof(GridLengthAnimation));
        EasingFunctionProperty = DependencyProperty.Register("EasingFunction", typeof(IEasingFunction), typeof(GridLengthAnimation));
    }

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

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

    public IEasingFunction EasingFunction
    {
        get
        {
            return (IEasingFunction)GetValue(GridLengthAnimation.EasingFunctionProperty);
        }
        set
        {
            SetValue(GridLengthAnimation.EasingFunctionProperty, value);
        }

    }

    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);
        }
    }

    public override object GetCurrentValue(object defaultOriginValue, object defaultDestinationValue, AnimationClock animationClock)
    {
        double fromValue = ((GridLength)GetValue(GridLengthAnimation.FromProperty)).Value;
        double toValue = ((GridLength)GetValue(GridLengthAnimation.ToProperty)).Value;

        IEasingFunction easingFunction = this.EasingFunction;

        double progress = (easingFunction != null) ? easingFunction.Ease(animationClock.CurrentProgress.Value) : animationClock.CurrentProgress.Value;

        if (fromValue > toValue)
        {
            return new GridLength((1 - progress) * (fromValue - toValue) + toValue, this.To.IsStar ? GridUnitType.Star : GridUnitType.Pixel);
        }
        else
        {
            return new GridLength((progress) * (toValue - fromValue) + fromValue, this.To.IsStar ? GridUnitType.Star : GridUnitType.Pixel);
        }
    }
}
如果我注释掉MouseEnter事件处理程序中的代码,拆分器工作正常,否则它将停止工作。有什么想法吗?

您必须设置动画的属性。默认值为
HoldEnd
,这意味着动画在结束后保留最终值。如果将FillBehavior设置为
Stop
,则动画值将恢复为设置动画之前的值

如果将以下行添加到事件处理程序代码中,则应按预期工作:

...
da.FillBehavior = FillBehavior.Stop;
c2.Width = da.To; // set final value before starting the animation
c2.BeginAnimation(ColumnDefinition.WidthProperty, da);

如果在开始动画之前设置最终值会产生闪烁效果,您可以改为在
已完成的
处理程序中设置最终值:

...
da.FillBehavior = FillBehavior.Stop;
da.Completed += (s, e) => c2.Width = da.To;
c2.BeginAnimation(ColumnDefinition.WidthProperty, da);

仅对前面的答案进行扩展(将进行评论,但stackoverflow主管不允许):

对我来说,在开始动画之前设置最终值会在动画开始之前的一瞬间为我的栅格生成难看的闪烁效果

我所做的是使用上面提到的FillBehavior.Stop,但订阅Animation.Completed事件并在其中设置网格列的最终高度

就像一个没有任何闪烁的魅力

...
da.FillBehavior = FillBehavior.Stop;
da.Completed += (s, e) => c2.Width = da.To;
c2.BeginAnimation(ColumnDefinition.WidthProperty, da);