C# 在第二个选项卡中卸载了两个加载的事件,但没有任何干预,这是一个bug吗?

C# 在第二个选项卡中卸载了两个加载的事件,但没有任何干预,这是一个bug吗?,c#,wpf,C#,Wpf,这是我的主窗口代码,其中包含一个TabControl: <Window x:Class="TabControlNS.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsof

这是我的主窗口代码,其中包含一个
TabControl

<Window x:Class="TabControlNS.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:TabControlNS"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <TabControl Visibility="Visible">
            <TabItem Header="Item2">
            </TabItem>
            <TabItem Header="Item1">
                <ContentControl Loaded="ContentControl_Loaded">
                    <local:View/>
                </ContentControl>        
            </TabItem>              
            <TabItem Header="Item3"/>
            <TabItem Header="Item4"/>
        </TabControl>

    </Grid>
</Window>

<UserControl x:Class="TabControlNS.View"
             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" 
             xmlns:local="clr-namespace:TabControlNS"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <Grid x:Name="grid">

    </Grid>
</UserControl>
由于
local:View
控件嵌入在“Item1”中,因此
View\u Loaded
将被调用两次(一次在窗口启动时调用,另一次在“Item1”即将查看时调用)其间未调用任何已卸载事件。

,这显然是一个bug

我鼓励你报告那些明显错误的错误, 比如

  • 已卸载事件,但未加载匹配的
  • 两个加载的事件,没有中间卸载
  • 元素清晰可见且处于活动状态,但未加载

还是这样?微软能用这样的控件制造出这样一个基本的bug吗?如何解释这一点?

我不确定这是否是一个bug,但在WPF行为中确实有几个控件

在未卸载
的情况下,将两次提升
加载的
的控件为:

  • TabControl
  • 弹出窗口
将控件添加到可视化树时,加载的
事件将引发到其所有子级。当子项显示或打开时,
Loaded
事件将再次引发。当子项关闭时,
卸载
事件将引发一次。当从可视树中删除
选项卡控件
弹出窗口
时,将再次引发
卸载
事件


将选项卡控件添加到可视树时:

  • TabControl-Loaded
    ->
    TabItem0-Loaded
    ->
    TabItem1-Loaded
    ->
当选项卡控件更改选项卡时:

  • 已卸载旧的活动选项卡
    ->
    已加载新的活动选项卡
这意味着所有的
TabItem
s将被
加载
两次,而
卸载
两次

弹出窗口
具有类似的行为

将弹出窗口添加到可视树时:

  • 已加载弹出窗口
    ->
    已加载子项
当弹出窗口打开时:

  • 加载的子项
当弹出窗口关闭时:

  • 卸载的子对象
从可视树中删除弹出窗口时:

  • 弹出窗口已卸载
但如果弹出窗口打开并从可视树中删除:

  • 弹出式卸载
    ->
    子级卸载
    (这可能不是很正常。)

事实上,我相信WPF有很多bug。我和我的朋友将它们发布在GitHub上:


值得一看:当显式添加TabItem时,确实会立即加载它。但是,如果使用ItemsSource属性,则不应发生这种情况。
public partial class View : UserControl
{
    public System.Windows.Forms.Integration.WindowsFormsHost host;
    public View()
    {
        InitializeComponent();
        IsKeyboardFocusWithinChanged += View_IsKeyboardFocusWithinChanged;

        host = new System.Windows.Forms.Integration.WindowsFormsHost();
        var mtbDate = new System.Windows.Forms.MaskedTextBox("00/00/0000");
        grid.Children.Add(host);
        this.Loaded += View_Loaded;
        this.Unloaded += View_Unloaded;
    }

    private double LoadMinusUnloadCount = 0;

    private void View_Loaded(object sender, RoutedEventArgs e)
    {
        LoadMinusUnloadCount++;   
    }

    private void View_Unloaded(object sender, RoutedEventArgs e)
    {
        LoadMinusUnloadCount--;
    }

    private void View_IsKeyboardFocusWithinChanged(object sender, DependencyPropertyChangedEventArgs e)
    {
        Console.WriteLine($"View.IsKeyboardFocusedWithin = {IsKeyboardFocusWithin}");
    }
}