为什么WPF会在添加到TabControl后立即为视图触发Loaded事件?

时间:2021-04-29 23:59:51

I have a simple C# WPF application looking like this:

我有一个简单的C#WPF应用程序,如下所示:

为什么WPF会在添加到TabControl后立即为视图触发Loaded事件?

I'm adding Item2 programmatically, and I wonder why the Loaded event is fired both shortly after it has been added to the TabControl and then again when I open it.

我正在以编程方式添加Item2,我想知道为什么Loaded事件在它被添加到TabControl后不久就会被触发,然后当我打开它时再次触发。

The code for my MainWindow.xaml looks as follows:

我的MainWindow.xaml的代码如下所示:

<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">
    <Grid>
        <TabControl Name="MyTabControl" >
            <TabItem Name="Item1" Header="Item1">
                <local:Control1 />
            </TabItem>
        </TabControl>
    </Grid>
</Window>

And its code-behind is:

它的代码隐藏是:

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);
        }
    }
}

As you can see, I have one control called Control1 and another called Control2. They are defined with the following MyControl.xaml file:

如您所见,我有一个名为Control1的控件,另一个名为Control2。它们使用以下MyControl.xaml文件定义:

<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">
    <Grid>

    </Grid>
</UserControl>

And the following code-behind MyControl.xaml.cs:

以下代码隐藏MyControl.xaml.cs:

using System.Diagnostics;

namespace WpfApplication1
{
    public abstract partial class MyControl
    {
        protected abstract string MyName { get; }

        protected MyControl()
        {
            InitializeComponent();
            Loaded += (sender, args) => Debug.Print("Loaded {0}", MyName);
            Unloaded += (sender, args) => Debug.Print("Unloaded {0}", MyName);
        }
    }

    public class Control1 : MyControl
    {
        protected override string MyName => "Control1";
    }

    public class Control2 : MyControl
    {
        protected override string MyName => "Control2";
    }
}

When I open the application, I get the following console output:

当我打开应用程序时,我得到以下控制台输出:

Loaded Control1
Loaded Control2

And when I switch to Item2:

当我切换到Item2时:

Unloaded Control1
Loaded Control2

And back to Item1:

并回到第1项:

Unloaded Control2
Loaded Control1

The latter two make sense; when I navigate from a control it gets unloaded while the new control gets loaded.

后两者是有道理的;当我从控件导航时,它会在新控件加载时被卸载。

However, I don't understand why Control2 is loaded initially, before it has been shown. This causes Control2 to receive two Loaded events in a row, before it gets an Unloaded event.

但是,我不明白为什么在显示Control2之前最初加载它。这会导致Control2在获取Unloaded事件之前连续接收两个Loaded事件。

1 个解决方案

#1


0  

When we add Tab Items explicitly, each tab item is loaded and initialized immediately containing everything.(Please refer to this topic for more details Lazy loading WPF tab content)

当我们显式添加Tab项时,每个标签项都会立即加载并初始化,包含所有内容。(请参阅此主题以获取更多详细信息延迟加载WPF选项卡内容)

#1


0  

When we add Tab Items explicitly, each tab item is loaded and initialized immediately containing everything.(Please refer to this topic for more details Lazy loading WPF tab content)

当我们显式添加Tab项时,每个标签项都会立即加载并初始化,包含所有内容。(请参阅此主题以获取更多详细信息延迟加载WPF选项卡内容)