'Is there a "All Children loaded" event in WPF

I am listening for the loaded event of a Page. That event fires first and then all the children fire their load event. I need an event that fires when ALL the children have loaded. Does that exist?



Solution 1:[1]

Loaded is the event that fires after all children have been Initialized. There is no AfterLoad event as far as I know. If you can, move the children's logic to the Initialized event, and then Loaded will occur after they have all been initialized.

See MSDN - Object Lifetime Events.

Solution 2:[2]

You can also use the event: ContentRendered.

http://msdn.microsoft.com/en-us/library/ms748948.aspx#Window_Lifetime_Events

Solution 3:[3]

WPF cant provide that kind of an event since most of the time Data is determining whther to load a particular child to the VisualTree or not (for example UI elements inside a DataTemplate)

So if you can explain your scenario little more clearly we can find a solution specific to that.

Solution 4:[4]

One of the options (when content rendered):

this.LayoutUpdated += OnLayoutUpdated;

private void OnLayoutUpdated(object sender, EventArgs e)
            {
                if (!isInitialized && this.ActualWidth != 0 && this.ActualHeight != 0)
                {
                    isInitialized = true;
                    // Logic here
                }
            };

Solution 5:[5]

Put inside your xaml component you want to wait for, a load event Loaded="MyControl_Loaded" like

<Grid Name="Main" Loaded="Grid_Loaded"...>
<TabControl Loaded="TabControl_Loaded"...>
<MyControl Loaded="MyControl_Loaded"...>
...

and in your code

bool isLoaded;

private void MyControl_Loaded(object sender, RoutedEventArgs e)
{
   isLoaded = true;
}

Then, inside the Event triggers that have to do something but were triggering before having all components properly loaded, put if(!isLoaded) return; like

private void OnButtonChanged(object sender, RoutedEventArgs e)
{
    if(!isLoaded) return;

    ... // code that must execute on trigger BUT after load
}

Solution 6:[6]

I ended up doing something along these lines.. your milage may vary.

void WaitForTheKids(Action OnLoaded)
{
  // After your children have been added just wait for the Loaded
  // event to fire for all of them, then call the OnLoaded delegate

  foreach (ContentControl child in Canvas.Children)
  {
    child.Tag = OnLoaded; // Called after children have loaded
    child.Loaded += new RoutedEventHandler(child_Loaded);
  }
}
internal void child_Loaded(object sender, RoutedEventArgs e)
{
  var cc = sender as ContentControl;
  cc.Loaded -= new RoutedEventHandler(child_Loaded);

  foreach (ContentControl ctl in Canvas.Children)
  {
    if (!ctl.IsLoaded)
    {
      return;
    }
  }
  ((Action)cc.Tag)();
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 configurator
Solution 2 Bert-jan
Solution 3 Jobi Joy
Solution 4 Ievgen
Solution 5
Solution 6 Weezelboy