I'd like to animate the width and height of a wpf window. I've tried the following, which unfortunately just animates the width... the height of the window never changes.
I'm sure I've missed something silly and hope that by posting here someone will see my error!
Here's the code behind for a simple window with a button I've wired up do to the resize:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
this.AnimateWindowSize(ActualWidth + 200, ActualHeight + 200);
}
}
And here is the animation code I've written as an extension method so it could be applied to any window...
public static class WindowUtilties
{
public static void AnimateWindowSize(this Window target, double newWidth, double newHeight)
{
var sb = new Storyboard {Duration = new Duration(new TimeSpan(0, 0, 0, 0, 200))};
var aniWidth = new DoubleAnimationUsingKeyFrames();
var aniHeight = new DoubleAnimationUsingKeyFrames();
aniWidth.Duration = new Duration(new TimeSpan(0, 0, 0, 0, 200));
aniHeight.Duration = new Duration(new TimeSpan(0, 0, 0, 0, 200));
aniHeight.KeyFrames.Add(new EasingDoubleKeyFrame(target.ActualHeight, KeyTime.FromTimeSpan(new TimeSpan(0, 0, 0, 0, 00))));
aniHeight.KeyFrames.Add(new EasingDoubleKeyFrame(newHeight, KeyTime.FromTimeSpan(new TimeSpan(0, 0, 0, 0, 200))));
aniWidth.KeyFrames.Add(new EasingDoubleKeyFrame(target.ActualWidth, KeyTime.FromTimeSpan(new TimeSpan(0, 0, 0, 0, 00))));
aniWidth.KeyFrames.Add(new EasingDoubleKeyFrame(newWidth, KeyTime.FromTimeSpan(new TimeSpan(0, 0, 0, 0, 200))));
Storyboard.SetTarget(aniWidth, target);
Storyboard.SetTargetProperty(aniWidth, new PropertyPath(Window.WidthProperty));
Storyboard.SetTarget(aniHeight, target);
Storyboard.SetTargetProperty(aniHeight, new PropertyPath(Window.HeightProperty));
sb.Children.Add(aniWidth);
sb.Children.Add(aniHeight);
sb.Begin();
}
}
Thanks in advance for any help.
The one suggestion with newer DPs seemed a bit overkill for me, especially since the solution acknowledged that it still wouldn't resize simultaneously. In my quick experimentation, adding a delay (via Task.Run()) of even 1ms achieved the final result (window resizes). This solution also does not resize simultaneously and so the animation isn't as elegant as it could be, but it 'works' in the end.
After Joe's comment of using pinvoke and dependency properties I ended up with this code. I'll apologize now if the code is long and I shouldn't have put it all here. The math is not perfect on the sizes. There is quite a difference between the WPF Actual(Height/Width) versus the Rect.Height/Width, it may take some calculations to get the exact sizes you want.
This was added to the MainWindow class
And in the OP's code I changed the height and width target properties accordingly
to
Original answer:
From what I have found there is no problem with your code. When I changed the order in which I was adding the animations to the storyboard (sb.Children.Add) instance, I got the height animating with no width.
This leads me to believe that while the first animation is happening, the other animation becomes invalid.
All I could come up with is having them animate one after the other by having one animation be slightly longer than the other. The longer animation will occur once the first animation completed.
Not even using XAML storyboards could I get both height and width of the window to resize simultaneously.