Loaded event of a WPF user control fires more than once
Asked Answered
D

4

45

To implement a tab-based environment in WPF we need to convert our forms to user controls, however when doing this, the Loaded event of the user control is called two times.

While searching on the internet other people also pointed this issue. How can we ensure that loaded event is called only once? Because when it is called multiple times, initialization of our controls happens multiple times.

Disini answered 6/8, 2010 at 5:51 Comment(3)
I tried reproducing this in an empty .NET 4.0 WPF application and the Loaded event only fired once. Have you tried looking at the call stack to see if maybe something weird is going on in the .NET Framework before it fires the Loaded event?Tristan
Place your user control inside a tab control, and you'll be able to reproduce the issue when switching tabs.Electrochemistry
Try using Pages and Frames. It's much simpler and cleaner for grouping controls.Manicurist
A
51

As explained in this blog, the Loaded event is fired when ever a control is about to be rendered (i.e. added to the visual tree).

There are several controls that would cause your control to be loaded/unloaded multiple times. For example, the native WPF TabControl only renders the content of the selected tab. So when you select a new tab, the content of the previously selected tab is unloaded. If you click back to the previously selected tab, then it's content is reloaded.

One work around is to use a Boolean to flag whether you have already initialized your control, as suggested by others. Alternatively, you may be able to use the Initialized event instead.

Artemas answered 3/3, 2011 at 20:56 Comment(3)
I'm using TabControl's ItemsSource to bind several tabs and use DataTemplate to bind ViewModel to the tab views. In my case, not only is the Loaded event fired again but also the constructor of the tab view is called again. It seems that WPF is re-creating my tab control completely each time I switch the tab.Highspirited
@Highspirited I'm facing the same issue, any solution?Thorium
@Thorium This is an issue that we can't change. So I save everything in the ViewModel and let WPF recreate it every time.Highspirited
C
28

Your routed event handler can (and should) remove itself from the Loaded hook as the first thing it does.

public class MyClass : Window
{
    public MyClass()
    {
        Loaded += MyLoadedRoutedEventHandler;
    }

    void MyLoadedRoutedEventHandler(Object sender, RoutedEventArgs e)
    {
        Loaded -= MyLoadedRoutedEventHandler;
        /// ...
    }
};
Chaste answered 3/5, 2012 at 1:0 Comment(2)
Well.. your suggestion has certainly saved my sorry ass, Glenn... but can you explain why this removal should take place INSIDE the event handler? ThanksCatchall
@RichardHammond Because, at what earlier opportunity can you positively be assured that the event has indeed successfully fired? Where else would you suggest to put the removal?Chaste
B
3

Set a loaded flag in the event, and, if the flag has already been set, don't do anything.

Broadcast answered 6/8, 2010 at 5:52 Comment(1)
thanks for your suggestion, is this really a genuine issue and loaded event called two times due to tabDisini
N
0

As mentioned above,you can use bool flag for it.

bool isPageLoadingForFirstTime = true;

public void LoadedEvent()
{
  if(ispageLoadingForFirstTime)
   {
      //do something
      ispageLoadingForFirstTime = false;
   }
}
Neils answered 21/12, 2021 at 12:32 Comment(1)
Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.Burnt

© 2022 - 2024 — McMap. All rights reserved.