Search code examples
wpf

WPF, Loaded event, IsLoaded property


If I attach a handler to the Loaded event of an element (no matter if it is in the VS designer or in the code), it sets the IsLoaded property to true.

For instance, I have a TabControl with two TabItems. There is a button on each TabItem. The first TabItem is the default item (selected when my window is shown). The Button on the second TabItem has attached the Loaded event. In this case, the button on the first TabItem has IsLoaded set to true and the button on the second TabItem should be set to false but it is set to true.

When I unset the Loaded event it works as expected - the first button has IsLoaded true, the second has false.

Is this a wpf bug or am I doing something wrong?

EDIT:

See an example.

This code causes the IsLoaded property of btn2 set to True (Note: the btn2_Loaded method is empty).

XAML:

    <Window x:Class="WpfApplication1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
    <Grid>
        <TabControl>
            <TabItem Header="Tab1">
                <Button x:Name="btn1" Click="btn1_Click" />
            </TabItem>

            <TabItem Header="Tab2">
                <Button x:Name="btn2" Loaded="btn2_Loaded" />
            </TabItem>
        </TabControl>
    </Grid>
</Window>

C#:

    private void btn1_Click(object sender, RoutedEventArgs e)
    {
        MessageBox.Show(this.btn2.IsLoaded.ToString());
    }

Start the application and just click the btn1.

Now remove the Loaded handler:

            <TabItem Header="Tab2">
                <Button x:Name="btn2" />
            </TabItem>

Start the application again and click the btn1.

Now the IsLoaded is False! Why is this happening? Attaching an event handler causes loading of the particular element?


Solution

  • This is neither a bug in WPF nor are you doing something wrong. The MSDN page on Object Lifetime Events says that

    The Loaded event is raised before the final rendering, but after the layout system has calculated all necessary values for rendering.

    You can not make any more precise assumption on when exactly Loaded is called. In your case i guess WPF delays loading of the non-visible (i.e. not yet rendered) elements, unless a Loaded handler is attached. It is just free to do so.