SuperDisk
SuperDisk

Reputation: 2840

WPF and Blend: Resizing window doesn't work

I've set a storyboard to enlarge and shrink a window. These work fine in the Blend editor, but when actually running, they just don't work at all.

The window is supposed to expand/shrink at the same rate horizontally as vertically.

What's the fix to this?

enter image description here

Here's my XAML.

<Window x:Name="window" x:Class="MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="32" Width="32" ResizeMode="NoResize" WindowStyle="None">
    <Window.Resources>
        <Storyboard x:Key="GrowFrame">
            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Width)" Storyboard.TargetName="window">
                <EasingDoubleKeyFrame KeyTime="0" Value="32"/>
                <EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="256">
                    <EasingDoubleKeyFrame.EasingFunction>
                        <BackEase EasingMode="EaseOut" Amplitude="0.25"/>
                    </EasingDoubleKeyFrame.EasingFunction>
                </EasingDoubleKeyFrame>
            </DoubleAnimationUsingKeyFrames>
            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Height)" Storyboard.TargetName="window">
                <EasingDoubleKeyFrame KeyTime="0" Value="32"/>
                <EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="256">
                    <EasingDoubleKeyFrame.EasingFunction>
                        <BackEase EasingMode="EaseOut" Amplitude="0.25"/>
                    </EasingDoubleKeyFrame.EasingFunction>
                </EasingDoubleKeyFrame>
            </DoubleAnimationUsingKeyFrames>
            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="window">
                <EasingDoubleKeyFrame KeyTime="0" Value="0.5"/>
                <EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="1">
                    <EasingDoubleKeyFrame.EasingFunction>
                        <BackEase EasingMode="EaseOut" Amplitude="0.25"/>
                    </EasingDoubleKeyFrame.EasingFunction>
                </EasingDoubleKeyFrame>
            </DoubleAnimationUsingKeyFrames>
            <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="window">
                <EasingColorKeyFrame KeyTime="0" Value="Transparent"/>
                <EasingColorKeyFrame KeyTime="0:0:0.5" Value="White">
                    <EasingColorKeyFrame.EasingFunction>
                        <BackEase EasingMode="EaseOut"/>
                    </EasingColorKeyFrame.EasingFunction>
                </EasingColorKeyFrame>
            </ColorAnimationUsingKeyFrames>
        </Storyboard>
        <Storyboard x:Key="ShrinkFrame">
            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Width)" Storyboard.TargetName="window">
                <EasingDoubleKeyFrame KeyTime="0" Value="256"/>
                <EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="32">
                    <EasingDoubleKeyFrame.EasingFunction>
                        <CubicEase EasingMode="EaseInOut"/>
                    </EasingDoubleKeyFrame.EasingFunction>
                </EasingDoubleKeyFrame>
            </DoubleAnimationUsingKeyFrames>
            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Height)" Storyboard.TargetName="window">
                <EasingDoubleKeyFrame KeyTime="0" Value="256"/>
                <EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="32">
                    <EasingDoubleKeyFrame.EasingFunction>
                        <CubicEase EasingMode="EaseInOut"/>
                    </EasingDoubleKeyFrame.EasingFunction>
                </EasingDoubleKeyFrame>
            </DoubleAnimationUsingKeyFrames>
            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="window">
                <EasingDoubleKeyFrame KeyTime="0" Value="1"/>
                <EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="0.5">
                    <EasingDoubleKeyFrame.EasingFunction>
                        <CubicEase EasingMode="EaseInOut"/>
                    </EasingDoubleKeyFrame.EasingFunction>
                </EasingDoubleKeyFrame>
            </DoubleAnimationUsingKeyFrames>
            <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="window">
                <EasingColorKeyFrame KeyTime="0" Value="White"/>
                <EasingColorKeyFrame KeyTime="0:0:0.5" Value="Transparent">
                    <EasingColorKeyFrame.EasingFunction>
                        <CubicEase EasingMode="EaseInOut"/>
                    </EasingColorKeyFrame.EasingFunction>
                </EasingColorKeyFrame>
            </ColorAnimationUsingKeyFrames>
        </Storyboard>
    </Window.Resources>
    <Window.Triggers>
        <EventTrigger RoutedEvent="Mouse.MouseEnter">
            <BeginStoryboard Storyboard="{StaticResource GrowFrame}"/>
        </EventTrigger>
        <EventTrigger RoutedEvent="Mouse.MouseLeave">
            <BeginStoryboard x:Name="ShrinkFrame_BeginStoryboard" Storyboard="{StaticResource ShrinkFrame}"/>
        </EventTrigger>
    </Window.Triggers>
</Window>

Upvotes: 2

Views: 530

Answers (3)

B.K.
B.K.

Reputation: 10162

As others have pointed out, there's a bug in the new framework releases that prevents synchronous animation. However, here's a quick little solution that works very well for me. It's beyond simple, so I don't think any explanation is in order. It works, and that's all that matters:

XAML:

<Window x:Class="App.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="32" Width="32" ResizeMode="NoResize" WindowStyle="None"
    MouseEnter="MouseEntered" MouseLeave="MouseLeft">
</Window>

Code-Behind:

using System.Windows;
using System.Windows.Input;

namespace App
{
    public partial class MainWindow : Window
    {
        private const int MAX_WINDOW_SIZE = 256;
        private const int MIN_WINDOW_SIZE = 32;
        private const int ANIMATION_SPEED = 10;

        public MainWindow()
        {
            InitializeComponent();
        }

        private void MouseEntered(object sender, MouseEventArgs e)
        {
            while (this.Width <= MAX_WINDOW_SIZE)
            {
                this.Width += ANIMATION_SPEED;
                this.Height += ANIMATION_SPEED;
            }
        }

        private void MouseLeft(object sender, MouseEventArgs e)
        {
            while (this.Width >= MIN_WINDOW_SIZE)
            {
                this.Width -= ANIMATION_SPEED;
                this.Height -= ANIMATION_SPEED;
            }
        }
    }
}

Upvotes: 0

fastboxster
fastboxster

Reputation: 59

Alternatively, just use a fixed sized transparent window as a workaround:

   <Window x:Name="window" x:Class="RectangleWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="RectangleWindow" Height="300" Width="300"  ResizeMode="NoResize" WindowStyle="None" 
            Background="Transparent" AllowsTransparency="True">
        <Window.Resources>
            <Storyboard x:Key="GrowFrame">
                <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Width)" Storyboard.TargetName="insideRectangle">
                    <EasingDoubleKeyFrame KeyTime="0" Value="32"/>
                    <EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="256">
                        <EasingDoubleKeyFrame.EasingFunction>
                            <BackEase EasingMode="EaseOut" Amplitude="0.25"/>
                        </EasingDoubleKeyFrame.EasingFunction>
                    </EasingDoubleKeyFrame>
                </DoubleAnimationUsingKeyFrames>
                <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Height)" Storyboard.TargetName="insideRectangle">
                    <EasingDoubleKeyFrame KeyTime="0" Value="32"/>
                    <EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="256">
                        <EasingDoubleKeyFrame.EasingFunction>
                            <BackEase EasingMode="EaseOut" Amplitude="0.25"/>
                        </EasingDoubleKeyFrame.EasingFunction>
                    </EasingDoubleKeyFrame>
                </DoubleAnimationUsingKeyFrames>
            </Storyboard>
            <Storyboard x:Key="ShrinkFrame">
                <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Width)" Storyboard.TargetName="insideRectangle">
                    <EasingDoubleKeyFrame KeyTime="0" Value="256"/>
                    <EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="32">
                        <EasingDoubleKeyFrame.EasingFunction>
                            <CubicEase EasingMode="EaseInOut"/>
                        </EasingDoubleKeyFrame.EasingFunction>
                    </EasingDoubleKeyFrame>
                </DoubleAnimationUsingKeyFrames>
                <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Height)" Storyboard.TargetName="insideRectangle">
                    <EasingDoubleKeyFrame KeyTime="0" Value="256"/>
                    <EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="32">
                        <EasingDoubleKeyFrame.EasingFunction>
                            <CubicEase EasingMode="EaseInOut"/>
                        </EasingDoubleKeyFrame.EasingFunction>
                    </EasingDoubleKeyFrame>
                </DoubleAnimationUsingKeyFrames>
            </Storyboard>
        </Window.Resources>
        <Window.Triggers>
            <EventTrigger RoutedEvent="Mouse.MouseEnter">
                <BeginStoryboard Storyboard="{StaticResource GrowFrame}"/>
            </EventTrigger>
            <EventTrigger RoutedEvent="Mouse.MouseLeave">
                <BeginStoryboard x:Name="ShrinkFrame_BeginStoryboard" Storyboard="{StaticResource ShrinkFrame}"/>
            </EventTrigger>
        </Window.Triggers>

        <Rectangle x:Name="insideRectangle" Fill="White" 
          Width="50" Height="50"
          HorizontalAlignment="Left"
          VerticalAlignment="Top">
            <Rectangle.BitmapEffect>
                <DropShadowBitmapEffect/>
            </Rectangle.BitmapEffect>      
        </Rectangle>
    </Window>

Upvotes: 0

fastboxster
fastboxster

Reputation: 59

WPF does support both synchronized animations (as you attempted) and overlapping animations where you supply a HandoffBehavior. You might try that to see if it works as a workaround. However I think this is a known bug (https://connect.microsoft.com/VisualStudio/feedback/details/715415/window-width-height-animation-in-wpf-got-broken-on-net-framework-4-0). I'm shocked it has not been fixed by now.

Upvotes: 2

Related Questions