Wpf 设置动画时更改栅格列宽度

Wpf 设置动画时更改栅格列宽度,wpf,animation,grid,row,Wpf,Animation,Grid,Row,我有一个网格元素,它有两列和三行。最后一行的高度为0。。。我使用一个自定义动画类来设置height属性的动画,因为gridheight属性不是整数 动画效果很好,但当我激活它时,它似乎随机改变了第二列的宽度。。有时只是几个像素大,有时超过两倍的宽度 这是网格代码 <Grid > <Grid.ColumnDefinitions> <ColumnDefinition

我有一个网格元素,它有两列和三行。最后一行的高度为0。。。我使用一个自定义动画类来设置height属性的动画,因为gridheight属性不是整数

动画效果很好,但当我激活它时,它似乎随机改变了第二列的宽度。。有时只是几个像素大,有时超过两倍的宽度

这是网格代码

<Grid >
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition />
                            <ColumnDefinition Width="50"/>
                        </Grid.ColumnDefinitions>
                        <Grid.RowDefinitions>
                            <RowDefinition Height="1*" />
                            <RowDefinition Height="7"/>
                            <RowDefinition Name="LyricsRow" Height="1">

                                <RowDefinition.Style>
                                    <Style>
                                        <Style.Triggers>
                                            <DataTrigger Binding="{Binding Path=IsTrayOpen}" Value="True">
                                                <DataTrigger.EnterActions>
                                                    <BeginStoryboard>
                                                        <Storyboard>
                                                            <local:GridLengthAnimation
                                                              Storyboard.TargetProperty="Height"
                                                              From="0" To="150" Duration="0:0:0.3" >
                                                            </local:GridLengthAnimation>
                                                        </Storyboard>
                                                    </BeginStoryboard>
                                                </DataTrigger.EnterActions>
                                                <DataTrigger.ExitActions>
                                                    <BeginStoryboard>
                                                        <Storyboard>
                                                            <local:GridLengthAnimation
                                                              Storyboard.TargetProperty="Height"
                                                              From="150" To="0" Duration="0:0:0.5" />
                                                        </Storyboard>
                                                    </BeginStoryboard>
                                                </DataTrigger.ExitActions>
                                            </DataTrigger>
                                        </Style.Triggers>
                                    </Style>
                                </RowDefinition.Style>

                            </RowDefinition>
                        </Grid.RowDefinitions>


这有什么原因吗

这可能取决于“细胞”的含量


除了Width=“50”

之外,还可以尝试在columnDefinition上设置MaxWidth=“50”。对于那些可能对问题中提到的GridLengthAnimation实现感到疑惑的人,这里有一个(来自)

//
///为栅格长度值设置动画,就像double动画为double值设置动画一样
/// 
公共类GridLengthAnimation:AnimationTimeline
{
/// 
///返回要设置动画的对象的类型
/// 
公共重写类型TargetPropertyType
{
得到
{
返回类型(GridLength);
}
}
/// 
///创建动画对象的实例
/// 
///返回GridLengthAnimation的实例
受保护的覆盖System.Windows.Freezable CreateInstanceCore()
{
返回新的GridLengthAnimation();
}
/// 
///From属性的依赖项属性
/// 
public static readonly dependencProperty FromProperty=dependencProperty.Register(“From”),typeof(GridLength),
类型(GridLengthAnimation));
/// 
///From Dependency属性的CLR包装器
/// 
公共网格长度从
{
得到
{
return(GridLength)GetValue(GridLengthAnimation.FromProperty);
}
设置
{
SetValue(GridLengthAnimation.FromProperty,值);
}
}
/// 
///To属性的依赖项属性
/// 
public static readonly dependencProperty ToProperty=dependencProperty.Register(“To”),typeof(GridLength),
类型(GridLengthAnimation));
/// 
///To属性的CLR包装器
/// 
公共网格长度到
{
得到
{
返回(GridLength)GetValue(GridLengthAnimation.TopProperty);
}
设置
{
设置值(GridLengthAnimation.TopProperty,值);
}
}
/// 
///设置栅格let集的动画
/// 
///要设置动画的原始值
///终值
///动画时钟(计时器)
///返回要设置的新网格长度
公共重写对象GetCurrentValue(对象defaultOriginValue,
对象defaultDestinationValue,AnimationClock AnimationClock)
{
double fromVal=((GridLength)GetValue(GridLengthAnimation.FromProperty)).Value;
//检查是否从调用者设置了from
if(fromVal==1)
//将from设置为实际值
fromVal=((GridLength)defaultDestinationValue).Value;
double-toVal=((GridLength)GetValue(GridLengthAnimation.ToProperty)).Value;
if(fromVal>toVal)
返回新的GridLength((1-animationClock.CurrentProgress.Value)*(fromVal-toVal)+toVal,GridUnitType.Star);
其他的
返回新的GridLength(animationClock.CurrentProgress.Value*(toVal-fromVal)+fromVal,GridUnitType.Star);
}
}
谢谢!我必须更改fromVal=((GridLength)defaultDestinationValue);to fromVal=((GridLength)defaultOriginValue).Value;。但除此之外,它是完美的。
/// <summary>
/// Animates a grid length value just like the DoubleAnimation animates a double value
/// </summary>
public class GridLengthAnimation : AnimationTimeline
{
    /// <summary>
    /// Returns the type of object to animate
    /// </summary>
    public override Type TargetPropertyType
    {
        get
        {
            return typeof(GridLength);
        }
    }

    /// <summary>
    /// Creates an instance of the animation object
    /// </summary>
    /// <returns>Returns the instance of the GridLengthAnimation</returns>
    protected override System.Windows.Freezable CreateInstanceCore()
    {
        return new GridLengthAnimation();
    }

    /// <summary>
    /// Dependency property for the From property
    /// </summary>
    public static readonly DependencyProperty FromProperty = DependencyProperty.Register("From", typeof(GridLength),
            typeof(GridLengthAnimation));

    /// <summary>
    /// CLR Wrapper for the From depenendency property
    /// </summary>
    public GridLength From
    {
        get
        {
            return (GridLength)GetValue(GridLengthAnimation.FromProperty);
        }
        set
        {
            SetValue(GridLengthAnimation.FromProperty, value);
        }
    }

    /// <summary>
    /// Dependency property for the To property
    /// </summary>
    public static readonly DependencyProperty ToProperty = DependencyProperty.Register("To", typeof(GridLength),
            typeof(GridLengthAnimation));

    /// <summary>
    /// CLR Wrapper for the To property
    /// </summary>
    public GridLength To
    {
        get
        {
            return (GridLength)GetValue(GridLengthAnimation.ToProperty);
        }
        set
        {
            SetValue(GridLengthAnimation.ToProperty, value);
        }
    }

    /// <summary>
    /// Animates the grid let set
    /// </summary>
    /// <param name="defaultOriginValue">The original value to animate</param>
    /// <param name="defaultDestinationValue">The final value</param>
    /// <param name="animationClock">The animation clock (timer)</param>
    /// <returns>Returns the new grid length to set</returns>
    public override object GetCurrentValue(object defaultOriginValue,
        object defaultDestinationValue, AnimationClock animationClock)
    {
        double fromVal = ((GridLength)GetValue(GridLengthAnimation.FromProperty)).Value;
        //check that from was set from the caller
        if (fromVal == 1)
            //set the from as the actual value
            fromVal = ((GridLength)defaultDestinationValue).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);
    }
}