平滑动画wpf窗口宽度和高度以及left和top属性

时间:2014-06-10 11:11:22

标签: c# wpf dependency-properties wpf-animation

我无法使用top和left属性动画窗口的高度和宽度 (如果你想运行它,链接到下载示例就在这个问题的最后。)

在我运行此动画时,我的窗口首先平滑移动到新位置(在上下左右平滑变化),并且在窗口移动期间平滑地设置动画宽度属性。 但窗口高度无响应 .. 然后窗口高度从一个值(旧高度)跳到新的高度。

我的WPF应用程序很简单 - 仅用于测试(4个属性,1个按钮和1个功能):

首先,我将此属性添加到我的窗口(文件:MainWindow.xaml.cs):

    /// <summary>
    /// Position to lock for change size in horizontal way (x)
    /// </summary>
    public static readonly DependencyProperty LocationLockHorizontalProperty = DependencyProperty.Register("LocationLockHorizontal", typeof(AlignmentX), typeof(Window));
    /// <summary>
    /// Position to lock for change size in vertical way (y)
    /// </summary>
    public static readonly DependencyProperty LocationLockVerticalProperty = DependencyProperty.Register("LocationLockVertical", typeof(AlignmentY), typeof(Window));
    /// <summary>
    /// Location to lock for change size.
    /// </summary>
    public AlignmentX LocationLockHorizontal
    {
        get { return (AlignmentX)GetValue(LocationLockHorizontalProperty); }
        set { SetValue(LocationLockHorizontalProperty, value); }
    }
    /// <summary>
    /// Location to lock for change size.
    /// </summary>
    public AlignmentY LocationLockVertical
    {
        get { return (AlignmentY)GetValue(LocationLockVerticalProperty); }
        set { SetValue(LocationLockVerticalProperty, value); }
    }

然后我在同一个文件中添加了一个创建和启动动画的新程序:

public void AnimateResize(double changeWidth = 0d, double changeHeight = 0d, double durationMilisec = 200.0)
{
    Storyboard sb = new Storyboard();

    DoubleAnimation daw;
    DoubleAnimation dah;

    // animate window width
    if (changeWidth != 0.0)
    {
        daw = new DoubleAnimation();
        daw.From = this.ActualWidth;
        daw.To = this.ActualWidth + changeWidth;
        daw.Duration = new Duration(TimeSpan.FromMilliseconds(durationMilisec));
        daw.AccelerationRatio = 0.4;
        daw.DecelerationRatio = 0.6;
        // this.BeginAnimation(Window.WidthProperty, daw);
        Storyboard.SetTarget(daw, this);
        Storyboard.SetTargetProperty(daw, new PropertyPath(Window.WidthProperty));
        sb.Children.Add(daw);
    }

    // animate window height
    if (changeHeight != 0.0)
    {
        dah = new DoubleAnimation();
        dah.From = this.ActualHeight;
        dah.To = this.ActualHeight + changeHeight;
        dah.Duration = new Duration(TimeSpan.FromMilliseconds(durationMilisec));
        dah.AccelerationRatio = 0.4;
        dah.DecelerationRatio = 0.6;
        Storyboard.SetTarget(dah, this);
        Storyboard.SetTargetProperty(dah, new PropertyPath(Window.HeightProperty));
        sb.Children.Add(dah); // this.BeginAnimation(Window.HeightProperty, dah);
    }

    DoubleAnimation dax;
    DoubleAnimation day;

    // animate window move in horizontal way
    if (LocationLockHorizontal == AlignmentX.Center || LocationLockHorizontal == AlignmentX.Right)
    {
        dax = new DoubleAnimation();
        dax.From = this.Left;
        switch (LocationLockHorizontal)
        {
            case AlignmentX.Center:
                dax.To = this.Left - changeWidth / 2.0;
                break;
            case AlignmentX.Right:
                dax.To = this.Left - changeWidth;
                break;
        }
        dax.Duration = new Duration(TimeSpan.FromMilliseconds(durationMilisec));
        dax.AccelerationRatio = 0.4; dax.DecelerationRatio = 0.6;

        Storyboard.SetTarget(dax, this);
        Storyboard.SetTargetProperty(dax, new PropertyPath(Window.LeftProperty));
        sb.Children.Add(dax); // this.BeginAnimation(Window.LeftProperty, dax);
    }

    // animate window move vertical 
    if (LocationLockVertical == AlignmentY.Center || LocationLockVertical == AlignmentY.Bottom)
    {
        day = new DoubleAnimation();
        day.From = this.Top;

        switch (LocationLockVertical)
        {
            case AlignmentY.Center:
                day.To = this.Top - changeHeight / 2.0;
                break;
            case AlignmentY.Bottom:
                day.To = this.Top - changeHeight;
                break;
        }
        day.Duration = new Duration(TimeSpan.FromMilliseconds(durationMilisec));
        day.AccelerationRatio = 0.4; day.DecelerationRatio = 0.6;

        Storyboard.SetTarget(day, this);
        Storyboard.SetTargetProperty(day, new PropertyPath(Window.TopProperty));
        sb.Children.Add(day); // this.BeginAnimation(Window.TopProperty, day);
    }
    sb.Begin();
}

在同一文件MyWindow中的MainWindow.xaml.cs初始化中,属性设置为此值(将动画垂直固定到底部并水平居中):

public MainWindow()
{
    InitializeComponent();
    LocationLockHorizontal = AlignmentX.Center; // fix center point when animate resizing
    LocationLockVertical = AlignmentY.Bottom; // lock bottom corner of application
}

我的应用程序有1个按钮,我为之前的程序随机调用设置了click事件:

private void Button_Click(object sender, RoutedEventArgs e)
{
    this.AnimateResize(new Random().NextDouble() * 400.0 - 200.0, new Random().NextDouble() * 500.0 - 250.0, 1000.0);
}

完整示例这里是我的xaml MainWindow.xaml

<Window x:Class="Test_HeightAndTopAnimation.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="300" WindowStartupLocation="CenterScreen">
  <Grid>
    <Button Content="Button" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click"/>
  </Grid>
</Window>

我阅读了几篇文章(Wpf - Animate height from bottom up - 我没有网格,或WPF: Animation is not smooth)但没有任何与此问题相关的内容。

使用示例链接到zip文件Application code on Google Drive

只有最后一点:我使用Windows7 64位和.NET 4.5

0 个答案:

没有答案