Lifetime events of a WPF application

Introduction

This article is a tutorial for beginners. It talks about lifetime events of an WPF application.

One common problem for WPF newbies is the lack of understanding of order of events which confuses them when they try to add initialization, cleanup or safe shutdown code.
In this article I will underlie basic concepts regarding that.

Events in WPF

We can classify events in WPF as lifetime events, input
events and custom events.

Custom events are events that developers implement by declaring their own delegate and an event wrapper surrounding it.

We will be concentrating only on lifetime events.

Lifetime events

Any object undergoes creation, use and destruction in its lifetime. Here I describe the lifetime events of a WPF object specifically Window and Application. These objects derive from Framework element.

I will be describing lifetime events below in the order they occur.

First Init order and then shutdown order.

Init order of events:

Any WPF object that derives from Framework class will undergo initialized, loaded and unloaded. Although the sample program shows Application, Window and a child object (simple button) overriding and handling lifetime events.

Startup: (Application)

This is the first lifetime event of Application to get fired. This is fired when
Application.Run() is called on the main window. But before the main window is shown. Please note that
Application.Run() is abstracted from the user. If you want to check the compiler generated code, search under your
projec\obj folder for file named App.g.i.cs (g stands for generated).

This is the event where you can process any commandline arguments received by your application.

Initialized: (Window)

This is the first lifetime event of window to get fired. This is an ordinary .Net event and not a routed event. When this event is fired at window level it means all its nested child controls are also already initialized. So child controls will fire their Initialized event followed by parent control and finally by Window. (Check the sample program, you will find that "Button_Initialized" event is fired before "Window_Initialized")

This occurs once the window is instantiated. This event is at the level of base class
FrameworkElement. Note that Styles and databinding will not be applied at this level. An interesting thing is
FrameworkElement defines services for Animation, styles and DataBinding.

SourceInitialized : (Window)

Acquire a proper legacy handle to your window. But still your window is not visible.

Called every time when this app's window comes foreground and also the first time app's window is rendered. Please note that only after this event window's
Activated event will be fired which actually makes sense

Activated: (Window)

Equivalent to GotFocus of a control. Called every time when window comes foreground and also the first time window is rendered. Only after this event window loaded event
isfired.

Loaded: (Window)

Your entire window is ready. Last stop before rendering. All animation, styles and databinding will be ready here. Any visual tweaks needs to be done here.

This works in reverse order when compared with Initialized event. It is raised from root to child element from the fully constructed logical element tree. So window Load event will be raised first followed by any child element events.

(Check the sample program, you will find that "Button_Loaded" event is fired after "Window_Loaded")

ContentRendered: (Window)

As the name implies it occurs after content was rendered. If there is no content this event will not be fired at all. Don't do any visual tweaks here. From here you may set a flag for your business logic that window is up, running and shown to the user for the first time.

Shutdown order of events:

Closing: (Window)

Trigger can be user action or programmatic. user action can be direct like clicking on close button. Logging of from windows did not rais this event. (SessionEnding event is handled in sample but not discussed here) In case of your program it can be a call to
Window.Close() or Application.ShutDown(). In any case the event can be cancelled by overriding
OnClosing() and setting CancelEventArgs.Cancel to true.

Deactivated: (Window)

Happens if window loses focus (this is window equivalent to
control.GotFocus()) or closed.

Deactivated: (Application)

Happens if user switches to another application (by Alt-Tab, taskbar or task manager etc.) or as effect of application closure.

Closed: (Window)

Window is closed but window elements are accessible. Last place to access them if there is a reason. Note after this window unloaded will be fired.

Exit: (Application)

Last but not least. Only the Run() method returns. (please refer to startup event above for note on Run() method). But if you have written your custom main() method instead of a generated one still you can add some business logic code here. Any quick resource freeing can be done here.

Other lifetime events

Unloaded

On wpf web apps on page navigation they occur. And also when the window theme changes this will be fired. (Verify the same by changing your windows theme when sample program is running.)

SessionEnding

This event is fired when user logs off from the system. Same can be cancelled by setting SessionEndingCancelEventArgs e.cancel as true.

About
the Sample code

Please find a WPF app that lists lifetime events of a window and application as they occur individually and combined. Because when some of application events are raised, window not yet created so it becomes important to somehow record the event data. Although simple logging is suffice I
modeled the same using a WPF hosted WCF client. Run "DataLogHostSvc" logger window before you run "OrderOfEvents" project. Other than that the attached sample is self-explanatory.

Note: As this sample uses net.tcp binding your windows firewall might block it and you need to add the exception.

Comments and Discussions

Under the Application Startup event,
You might mention that the App.xaml could have StartupURI set in the Application tag that can be the link between the Application and the first window (say Window1.xaml) .

This isn't a tutorial at all. This is just a summarization of the documentation you linked to. Essentially, "Cliff notes". This is a tip/trick at best, not an article.

To make this an article for beginners, you would have to discuss and demonstrate the events and how they work and when they fire. Examples would also need to be added.

But, you write the article text first, WITHOUT any code snippets, screen shots or diagrams. The text should stand on its own to cover the breadth of your topic. Once that's done, then you can add the code snippets and stuff to enhance the disucssion.

First of all i would like to thank you for the great article, but I would like you to add some links to the references. so it will be helpful for the people who are interested to read deep into the topics.