21

I am currently developing a wpf c# application. I have added to event triggers to the xaml of the form to fade in when the window loads and fades out when the window closes.

The fading in works perfectly without any problems but the fading out is not working.

I have it set up so the window fades in when it loads, has a timer to last 5 seconds, and then calls the form fade out event.

However, the window doesn't fade out it just closes straight away no animation. Below is the code I have for the fade in and fade out events

<Window.Triggers>
        <EventTrigger RoutedEvent="Window.Loaded">
            <BeginStoryboard>
                <Storyboard Name="FormFade">
                    <DoubleAnimation Name="FormFadeAnimation"
                                     Storyboard.TargetProperty="(Window.Opacity)"
                                     From="0.0" To="1.0" Duration="0:0:1"
                                     AutoReverse="False" RepeatBehavior="1x" />
                </Storyboard>
            </BeginStoryboard>
        </EventTrigger>
        <EventTrigger RoutedEvent="Window.Unloaded">
            <BeginStoryboard>
                <Storyboard Name="FormFadeOut" Completed="FormFadeOut_Completed">
                    <DoubleAnimation Name="FormFadeOutAnimation"
                                     Storyboard.TargetName="FormFadeOut"
                                     Storyboard.TargetProperty="(Window.Opacity)"
                                     From="1.0" To="0.0" Duration="0:0:1"
                                     AutoReverse="False" RepeatBehavior="1x" />
                </Storyboard>
            </BeginStoryboard>
        </EventTrigger>
    </Window.Triggers>

Thanks for any help you can offer.

H.B.
  • 166,899
  • 29
  • 327
  • 400
Boardy
  • 35,417
  • 104
  • 256
  • 447
  • possible duplicate of [Fading out a wpf window on close](http://stackoverflow.com/questions/867656/fading-out-a-wpf-window-on-close) – H.B. May 11 '11 at 02:45
  • Just a note to the above: Layered Windows `(WindowStyle=None, AllowsTransparency=True, Background=Transparent)` can be hardware rendered on Windows Vista or later and will avoid the black rectangular when its fading out. – AlexO Oct 02 '15 at 09:16

3 Answers3

40

Unloaded is not a suitable event for this, i'm not sure if this event can even occur for windows. You need to handle Closing, prevent it from actually closing, start an animation and close it when the Completed event of the animation occurs.

e.g.

<Window ...
        Closing="Window_Closing">
private void Window_Closing(object sender, CancelEventArgs e)
{
    Closing -= Window_Closing;
    e.Cancel = true;
    var anim = new DoubleAnimation(0, (Duration)TimeSpan.FromSeconds(1));
    anim.Completed += (s, _) => this.Close();
    this.BeginAnimation(UIElement.OpacityProperty, anim);
}
H.B.
  • 166,899
  • 29
  • 327
  • 400
  • I have tried what you have suggested and it is now coming up with an exception saying 'Window.Closing value cannot be assigned to property 'RoutedEvent of object System.Windows.EventTrigger – Boardy May 11 '11 at 02:38
  • Can you see the code? This is **not** inside of the EventTriggers at all. – H.B. May 11 '11 at 02:44
  • Sorry I misread your code, works perfectly, thanks for the help – Boardy May 11 '11 at 11:47
  • You're welcome, but please take more care to look around on SO first next time as this question has a duplicate which should not have been hard to find. – H.B. May 11 '11 at 11:50
  • Where to define Double Animation? – Chris Sep 05 '14 at 06:14
  • @Chris: I do not understand your question. – H.B. Sep 05 '14 at 15:06
  • Solved my problem. DoubleAnimation is defined in `System.Windows.Media.Animation.DoubleAnimation` – Chris Sep 05 '14 at 15:52
  • This is perfect for me! is there an opposite of this to make a popup fad IN? – Travis Tubbs Apr 11 '18 at 15:23
  • 1
    @TravisTubbs: You probably can set the opacity to 0 before opening the window/by default and then start an animation in `Loaded` in a similar way. – H.B. Apr 11 '18 at 15:52
6

just try this sample

<Window x:Class="FadeInAndOutWindow.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300" Closing="Window_Closing" x:Name="winHelp">
<Window.Triggers>
    <EventTrigger RoutedEvent="Window.Loaded">
        <BeginStoryboard>
            <Storyboard Name="FormFade">
                <DoubleAnimation  Name="FormFadeAnimation"
                                  Storyboard.TargetName="winHelp"
                                  Storyboard.TargetProperty="(Window.Opacity)"
                                  From="0.0"
                                  To="1.0"
                                  Duration="0:0:1"
                                  AutoReverse="False"
                                  RepeatBehavior="1x" />
            </Storyboard>
        </BeginStoryboard>
    </EventTrigger>
    <EventTrigger RoutedEvent="Window.Unloaded">
        <BeginStoryboard>
            <Storyboard Name="FormFadeOut"
                        Completed="FormFadeOut_Completed">
                <DoubleAnimation  Name="FormFadeOutAnimation"
                                  Storyboard.TargetName="winHelp"
                                  Storyboard.TargetProperty="(Window.Opacity)"
                                  From="1.0"
                                  To="0.0"
                                  Duration="0:0:1"
                                  AutoReverse="False"
                                  RepeatBehavior="1x" />
            </Storyboard>
        </BeginStoryboard>
    </EventTrigger>
</Window.Triggers>    
<Grid>

</Grid>

namespace FadeInAndOutWindow
{
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
        }

        private bool closeCompleted = false;


        private void FormFadeOut_Completed(object sender, EventArgs e)
        {
            closeCompleted = true;
            this.Close();
        }

        private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {

            if (!closeCompleted)
            {
                FormFadeOut.Begin();
                e.Cancel = true;
            }
        }

    }
}
Chris
  • 681
  • 1
  • 6
  • 16
Kishore Kumar
  • 21,449
  • 13
  • 81
  • 113
5

H.B. solution is good but don't close effectively the window because Close() call window_Closing and loop. Here my working solution:

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        AlreadyFaded = false;
    }

    bool AlreadyFaded;
    private void window_Closing(object sender, CancelEventArgs e)
    {
        if (!AlreadyFaded)
        {
            AlreadyFaded = true;
            e.Cancel = true;
            var anim = new DoubleAnimation(0, (Duration)TimeSpan.FromSeconds(1));
            anim.Completed += new EventHandler(anim_Completed);
            this.BeginAnimation(UIElement.OpacityProperty, anim);
        }
    }

    void anim_Completed(object sender, EventArgs e)
    {
         Close();
    }
  • This solution works great. I have created a BaseWindow class and all my windows inherit from it. All my windows have now this behaviour. Thank you for this improved version. – Alexandru Dicu Jul 26 '12 at 08:59
  • Works great, but for some reason it shows a black rectangular when its fading out.. any ideas on that? – Mittchel Oct 23 '12 at 21:20
  • 1
    The dialog must have AllowsTransparency="True" attribute to avoid the black rectangle. – Kemal Taşkın Aug 03 '18 at 14:16