WPF Animate Window Visibility Change

12,061

Solution 1

I did something like that (opacity goes to 0 during 2 seconds and window hides): just look at code, it's simple

MainWindow.xaml:

    <Storyboard x:Key="hideMe">
        <DoubleAnimation Storyboard.TargetProperty="Opacity" Duration="0:0:2" To="0.0"/>
        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility">
            <DiscreteObjectKeyFrame KeyTime="0:0:2" Value="{x:Static Visibility.Hidden}"/>
        </ObjectAnimationUsingKeyFrames>
    </Storyboard>
    <Storyboard x:Key="showMe">
        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility">
            <DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{x:Static Visibility.Visible}"/>
        </ObjectAnimationUsingKeyFrames>
        <DoubleAnimation Storyboard.TargetProperty="Opacity" Duration="0:0:5" To="0.75"/>
    </Storyboard>

MainWindow.xaml.cs

    public void ShowMe() {
        (FindResource("showMe") as Storyboard).Begin(this);
    }
    public void HideMe() {
        (FindResource("hideMe") as Storyboard).Begin(this);
    }

Just call HideMe() or ShowMe() instead of setting Visibility = Visibility.Hidden in code

Edit

WPF is slow when moving windows, so if you need sliding animation:

  1. Make a transparent window (AllowsTransparency="True" Background="Transparent" WindowStyle="None")

  2. Put all your controls onto opaque panel (Background="{StaticResource {x:Static SystemColors.ControlBrushKey}}")

  3. Animate this panel's Margin.Left from 0 to window's ActualWidth, then hide a window - this will remove a problem of saving window size

Solution 2

Playing with a Window's Opacity/Visibility requires a simple DoubleAnimation.

Example:

IsVisibleChanged += new DependencyPropertyChangedEventHandler(MainWindow_IsVisibleChanged);

void MainWindow_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
{
    DoubleAnimation da = new DoubleAnimation()
    {
        From = (IsVisible) ? 0 : 1,
        To = (IsVisible) ? 1 : 0,
        Duration = TimeSpan.FromSeconds(1)
    };

    BeginAnimation(Window.OpacityProperty, da);
}

Problem:

For this to work as expected, you need to set AllowsTransparency to True on your window. If you don't set this, your window with Opacity set to 0 will be Black.

The problem is for this property to be True, you need to have WindowStyle as None. Which means no frame around your window. That means no close, minimize, maximize, restore, title bar.

You have to provide a custom template (probably inherit Window class) to put these buttons up there.

Share:
12,061
John
Author by

John

Updated on July 01, 2022

Comments

  • John
    John almost 2 years

    I'm trying to figure out how to animate the change from Visibile to Hidden for a WPF window. The way I currently have the application working is that the window is normally hidden and when I move the mouse to the side of the screen it pops out, I'm using a boolean to visibility converter to do that but what I would like to do is to have the application slide out more smoothly on mouse over as well as slide back in again afterwards.

    I haven't don't anything with animations so I'm not sure how to do this. Firstly I'm not really sure what animation I should use the do this, secondly I'm not really sure whether I should trigger this on the "IsWindowVisibile" property in the viewmodel or if I should bind it to the VisibilityChanged event and thirdly I'm not sure if this is possible when the window size is variable.

    [Edit]

    If necessary I will 'take' an opacity solution but that's not exactly the 'sliding' effect I am trying to get.

  • John
    John over 13 years
    I'm trying to use your solution but while it fades in correctly when IsVisible == true, when IsVisibile == false it disappears straight away instead of the opacity changing and then disappearing
  • John
    John over 13 years
    This mostly works. My window is already transparent so I'm just binding it directly to the Window.Left property. I'm also doing it in code behind instead of XAML because I need to window width to depend on a view different factors
  • icaptan
    icaptan over 11 years
    I want to use this code for a DockPanel Panel, but I can not put Storyboard in the xmal file, how can i do it ?
  • Mykola Bohdiuk
    Mykola Bohdiuk over 11 years
    @icaptan You'll need to create a storyboard in code, like var sb = new Storyboard(); sb.Children.Add(opacityAnimation); sb.Children.Add(visibilityAnimation); sb.Begin(this)
  • icaptan
    icaptan over 11 years
    but why not in xaml file like your example ? i try it soon ! thanks
  • Mykola Bohdiuk
    Mykola Bohdiuk over 11 years
    @icaptan In the previous comment you stated that you cannot put it to xaml, so I proposed non-xaml way
  • Nick
    Nick about 9 years
    This is likely happening because we're being set to not visible before the animation is being run.
  • Pranesh Janarthanan
    Pranesh Janarthanan over 5 years
    @MykolaBogdiuk, I have tried your code, i set my window opacity to 0, i called window Show(), then your code ShowMe(). Window is not reaching opacity 1, there is a little transparent. i want it to reach opacity 1.0.
  • Mykola Bohdiuk
    Mykola Bohdiuk over 5 years
    @PraneshJanarthanan did you change 0.75 to 1.0 in <DoubleAnimation ...>?
  • Pranesh Janarthanan
    Pranesh Janarthanan over 5 years
    @MykolaBogdiuk, No, I am new to WPF. As already said in earlier comment. i Used your code exactly with a additional setting xaml window opacity to 0.
  • Mykola Bohdiuk
    Mykola Bohdiuk over 5 years
    @PraneshJanarthanan well, my question was the answer then. <DoubleAnimation ...> allows you to specify animation properties such as animated property TargetProperty, Duration and final property value To.
  • Pranesh Janarthanan
    Pranesh Janarthanan over 5 years
    @MykolaBogdiuk, Oh! I didn't notice your double animation line of code under ShowMe. So I just copied the same from your Hideme and specified the To=1.0. but your code To=0.75 was placed in the second order. So your code was in effect my code was overridden.