title: Why does WPF fire a Loaded event for a view as soon as it is added to a TabControl?
body: <p>I have a simple C# WPF application looking like this:</p>
  
  <p><a href="https://i.stack.imgur.com/XpVRc.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/XpVRc.png" alt="enter image description here"></a></p>
  
  <p>I'm adding Item2 programmatically, and I wonder why the <code>Loaded</code> event is fired both shortly after it has been added to the <code>TabControl</code> and then again when I open it.</p>
  
  <p>The code for my <code>MainWindow.xaml</code> looks as follows:</p>
  
  <pre><code>&lt;Window x:Class="WpfApplication1.MainWindow"
          xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
          xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
          xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
          xmlns:local="clr-namespace:WpfApplication1"
          mc:Ignorable="d"
          Title="MainWindow" Height="350" Width="525"&gt;
      &lt;Grid&gt;
          &lt;TabControl Name="MyTabControl" &gt;
              &lt;TabItem Name="Item1" Header="Item1"&gt;
                  &lt;local:Control1 /&gt;
              &lt;/TabItem&gt;
          &lt;/TabControl&gt;
      &lt;/Grid&gt;
  &lt;/Window&gt;
  </code></pre>
  
  <p>And its code-behind is:</p>
  
  <pre><code>using System.Windows;
  using System.Windows.Controls;
  
  namespace WpfApplication1
  {
      public partial class MainWindow
      {
          public MainWindow()
          {
              InitializeComponent();
              Loaded += OnLoaded;
          }
  
          private void OnLoaded(object sender, RoutedEventArgs routedEventArgs)
          {
              var item = new TabItem
              {
                  Content = new Control2(),
                  Header = "Item2"
              };
              MyTabControl.Items.Add(item);
          }
      }
  }
  </code></pre>
  
  <p>As you can see, I have one control called <code>Control1</code> and another called <code>Control2</code>. They are defined with the following <code>MyControl.xaml</code> file:</p>
  
  <pre><code>&lt;UserControl x:Class="WpfApplication1.MyControl"
               xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
               xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
               xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
               xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
               mc:Ignorable="d" 
               d:DesignHeight="300" d:DesignWidth="300"&gt;
      &lt;Grid&gt;
  
      &lt;/Grid&gt;
  &lt;/UserControl&gt;
  </code></pre>
  
  <p>And the following code-behind <code>MyControl.xaml.cs</code>:</p>
  
  <pre><code>using System.Diagnostics;
  
  namespace WpfApplication1
  {
      public abstract partial class MyControl
      {
          protected abstract string MyName { get; }
  
          protected MyControl()
          {
              InitializeComponent();
              Loaded += (sender, args) =&gt; Debug.Print("Loaded {0}", MyName);
              Unloaded += (sender, args) =&gt; Debug.Print("Unloaded {0}", MyName);
          }
      }
  
      public class Control1 : MyControl
      {
          protected override string MyName =&gt; "Control1";
      }
  
      public class Control2 : MyControl
      {
          protected override string MyName =&gt; "Control2";
      }
  }
  </code></pre>
  
  <p>When I open the application, I get the following console output:</p>
  
  <pre><code>Loaded Control1
  Loaded Control2
  </code></pre>
  
  <p>And when I switch to Item2:</p>
  
  <pre><code>Unloaded Control1
  Loaded Control2
  </code></pre>
  
  <p>And back to Item1:</p>
  
  <pre><code>Unloaded Control2
  Loaded Control1
  </code></pre>
  
  <p>The latter two make sense; when I navigate from a control it gets unloaded while the new control gets loaded.</p>
  
  <p>However, I don't understand why Control2 is loaded initially, before it has been shown. This causes Control2 to receive two <code>Loaded</code> events in a row, before it gets an <code>Unloaded</code> event.</p>