Reputation: 6734
I have a simple form that I want to shrink vertically using an animation. It works OK, except when the height of the form is approx. 16 pixels in height it "stops", then the animation completes (350 to 16, stops, then animation completes a brief moment later).
I see the same "jump" if I try the animation in the opposite direction (0 to 350, for example, it seems to wait, then immediately displays at 16 pixels and the animation continues to 350).
Here's a simple example which shows the issue:
<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>
Then in the .cs file for the window:
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);
}
}
It seems as if there is some internal border it's still trying to respect, even though I have it shut off.
I've tried a number of different combinations of borders, margins, etc. and can't seem to get it working nicely.
Upvotes: 1
Views: 242
Reputation: 5163
I believe this is an "as-design" feature, as the OS with dictate the actual minimum and maximum sizes, even if you try to change it to be smaller. I believe it comes down to the "minimum tracking size," which is a private field in the Window
class and is device dependent. Take a look at Window.GetWindowMinMax
.
I reproduced your situation on my laptop, however my window stopped shrinking at 14 pixels. I also noticed that all the content will shrink if you set the WindowStyle
to normal. I think you might have to do something with WM_GETIMINMAXINFO
and some PInvoke in order to change the tracking size; or make your own window control.
My definition/thoughts on tracking size is that a Window
needs to have some size/content to it in order for a user to actually re-position, re-size, etc., in other words track, the window. Microsoft probably doesn't want that, its not user-friendly. Set the window style to normal, and do the same thing, and you'll see the heights of the content in the window will all be set to 0; and that's possible because there is still a way to track the window.
Another interesting thing I've found is, execute your application from the bin
folder (not Visual Studio), fire the animation (with the Close() event commented out), and when the animation is done, go to the task bar, right click on the window, and click Maximize. On my machine, the application crashes--I'm not sure why.
Another thing to observe is that when you start the application and use Snoop to inspect the controls, you can change the Window.Height
to anything you want and it will adjust. Once you fire your animation, the Height
changes to something like 5.xxxxxxxxE-14, and ActualHeight
does not match. After the animation, if you try to change Window.Height
in Snoop, it will not take affect for whatever reason.
Since setting Height
seems to be restricted my .NET and the device, I'm not sure that's the easiest solution. Another approach you try is a ScaleTransform
and optionally mix the Height
animation. Here is the XAML I used:
<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>
This will first change the Height
to go to minimum, then you can continue to "close" the window by scaling the window down to 0. You could also scale in both X and Y directions, or just Y, and animate the window closing.
Upvotes: 2