wpf - 将动画应用到网格列后 GridSplitter 不起作用

标签 wpf animation gridsplitter

我是 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>

和这个:
        bool flag = true;
    private void bdRight_MouseEnter(object sender, MouseEventArgs e)
    {
        if (flag)
        {
            flag = false;
            var da = new GridLengthAnimation();
            da.From = new GridLength(c2.MinWidth);
            da.To = new GridLength(100);
            var ef = new BounceEase();
            ef.EasingMode = EasingMode.EaseOut;
            da.EasingFunction = ef;
            this.c2.BeginAnimation(ColumnDefinition.WidthProperty, da);
        }
    }

这是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 事件处理程序中的代码,则拆分器工作正常,否则,它将停止工作。有任何想法吗?

最佳答案

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

如果您将以下几行添加到您的事件处理程序代码中,它应该会按预期工作:

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

如果在开始动画之前设置最终值会产生闪烁效果,您可以改为在 Completed 中设置最终值。处理程序:
...
da.FillBehavior = FillBehavior.Stop;
da.Completed += (s, e) => c2.Width = da.To;
c2.BeginAnimation(ColumnDefinition.WidthProperty, da);

关于wpf - 将动画应用到网格列后 GridSplitter 不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9358025/

相关文章:

WPF 控件继承

c# - 由于 'Logger.Logger()' 的保护级别,我无法创建新的 NLog 记录器

jquery - 将动态 CSS 传递给 jQuery.animate

animation - CSS3 动画快退

java - 使用 EventDispatchThread 与不使用 EventDispatchThread 显示图像

wpf - 属性如何绑定(bind)到类型

C# 为 WPF 窗口禁用 aero 捕捉

wpf gridsplitter问题——两边都缩小

c# - 为什么我的 GridSplitter 没有出现?