使用WPF动画缩小窗口高度在完成之前停止在16像素

时间:2015-08-25 16:16:31

标签: wpf animation

我有一个简单的表单,我想使用动画垂直缩小。它工作正常,除非表格的高度约为。高度为16像素"停止"然后动画完成(350到16,停止,然后动画稍后完成)。

我看到了相同的"跳跃"如果我以相反的方向尝试动画(例如,0到350,它似乎等待,然后立即显示为16像素,动画继续到350)。

这是一个显示问题的简单示例:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        WindowStyle="None" Background="Transparent" AllowsTransparency="True" Padding="0"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <Storyboard x:Key="HideWindow">
            <DoubleAnimation Duration="0:0:3.8" 
                             Storyboard.TargetProperty="Height" 
                             From="350" 
                             To="0" 
                             AccelerationRatio=".1">
            </DoubleAnimation>
        </Storyboard>
    </Window.Resources>
    <Grid Background="Red">
        <Button Click="Button_Click" Width="50" Height="20">Hide</Button>                
    </Grid>
</Window>

然后在窗口的.cs文件中:

private void Button_Click(object sender, RoutedEventArgs e)
{
    var hide = FindResource("HideWindow") as Storyboard;
    if (hide != null)
    {
        hide.Completed += (s, ea) => Close();
        hide.Begin(this, true);
    }
}

似乎有一些内部边界,它仍然试图尊重,即使我关闭了它。

我尝试了许多不同的边框,边距等组合,但似乎无法让它正常运行。

1 个答案:

答案 0 :(得分:2)

我认为这是一个“设计”功能,因为操作系统会指示实际的最小和最大尺寸,即使您尝试将其更改为更小。我认为它归结为“最小跟踪大小”,它是Window类中的私有字段,并且取决于设备。看看Window.GetWindowMinMax

我在笔记本电脑上重现了你的情况,但是我的窗口停止了缩小到14像素。我还注意到,如果将WindowStyle设置为正常,则所有内容都会缩小。我想你可能需要对WM_GETIMINMAXINFO和一些PInvoke做些什么来改变跟踪大小;或制作自己的窗口控件。

我对跟踪大小的定义/想法是Window需要有一些大小/内容才能让用户实际重新定位,重新调整大小等等,换句话说,跟踪,窗户。微软可能不希望这样,它不是用户友好的。将窗口样式设置为正常,并执行相同的操作,您将看到窗口中内容的高度都将设置为0;这是可能的,因为仍有办法跟踪窗口。

我发现另一个有趣的事情是,从bin文件夹(不是Visual Studio)执行你的应用程序,激活动画(注释掉Close()事件),当动画完成时,转到任务栏,右键单击窗口,然后单击“最大化”。在我的机器上,应用程序崩溃 - 我不确定原因。

要注意的另一件事是,当您启动应用程序并使用Snoop检查控件时,您可以将Window.Height更改为您想要的任何内容并进行调整。触发动画后,Height会更改为5.xxxxxxxxE-14,而ActualHeight不匹配。在动画之后,如果您尝试在Snoop中更改Window.Height,则无论出于何种原因它都不会生效。

由于设置Height似乎限制了我的.NET和设备,我不确定这是最简单的解决方案。您尝试的另一种方法是ScaleTransform,并可选择混合Height动画。这是我使用的XAML:

<Window.Resources>
    <Storyboard x:Key="HideWindow">
        <DoubleAnimation Duration="0:0:3.5" 
                         BeginTime="0:0:0"
                         Storyboard.TargetProperty="Height"
                         From="350"
                         To="0">
        </DoubleAnimation>
        <DoubleAnimation Storyboard.TargetProperty="(Window.RenderTransform).(ScaleTransform.ScaleY)"  
                         To="0"
                         BeginTime="0:0:3.3"
                         Duration="0:0:0.3">
        </DoubleAnimation>
    </Storyboard>
</Window.Resources>
<Window.RenderTransform>
    <ScaleTransform ScaleY="1"/>
</Window.RenderTransform>

这将首先将Height更改为最小值,然后您可以通过将窗口缩小到0来继续“关闭”窗口。您还可以在X和Y方向上缩放,或者只是Y ,并关闭窗口的动画。