9 Şubat 2010 Salı

Initialized vs. Loaded

Today, I was implementing a simple user control UC, in WPF, that is composed of a CheckBox and a TextBox. I bound CheckBox's Content property to UC's Title property as;
   1: <CheckBox x:Name="chkTitle" 
   2:              Content="{Binding Title}" 
   3:              Height="30" />

It all worked well, until I came to a point where I have to set DataContext to of the UC to itself. Of course this is not much of a problem; since Bindings are updated through OnPropertyChanged method I overloaded and called from setters. The problem was, I encountered with two different events (when I follow the event option); Initialized and Loaded, that UserControl fires seperately for not a very apparent reason, apparently.

This subtle difference triggered me to google up the point with the title of this post as keywords; and I should have been feeling lucky to hit Mike Hillberg's post on the subject ( try it yourself ).

Those who are lazy enough not to read Mike's post should probably follow his words of wisdom:
"If you’re not sure which event to use, and you don’t want to read any more, use the Loaded event; it’s more often the right choice".

Mike has explained the difference of the events from a Layout perspective in his blog; and I will give an example from a Binding perspective.

   1: <TextBlock x:Name="txtPrice" Width="100"
   2:               Initialized="txtPrice_Initialized"
   3:               Loaded="txtPrice_Loaded"
   4:               >
   5:     <TextBlock.Text>
   6:         <Binding ElementName="cmbFruits" 
   7:                  Path="SelectedValue" />
   8:     </TextBlock.Text>
   9: </TextBlock>
  10:             
  11: <ComboBox   x:Name="cmbFruits" 
  12:             ItemsSource="{Binding Fruits}"
  13:             DisplayMemberPath="Name" 
  14:             SelectedValuePath="Price"
  15:             SelectedIndex="0"
  16:             />

In the above code snippet, TextBlock’s Text property is bound to the SelectedValue property of ComboBox. TextBlock’s both Initialized and Loaded events are handled in the codebehind.

When I debug the application, and step into Initialized event handler; TextBlock’s Text property is equal to Empty string; since by the time it is initialized, its data provider, cmbFruits; has not yet been initialized ( as it comes latter in the xaml code).  But when I step into TextBlock’s Loaded event handler; I see that its Text property is set to the selected Fruit’s price; because at that time, cmbFruits is initialized as SelectedIndex = 0.

In my example, the events are fired as the following order:
  • TextBlock is initialized.
  • ComboBox is initialized.
  • Window is initialized.
  • Window is loaded.
  • TextBlock is loaded.
  • ComboBox is loaded.
I dont want to be repeating Mike, so I am not going to explain the order; if you are curious about it, you should read his post.

Hope it helps for a why question. Enjoy.