Два загруженных события без вмешательства Unloaded во второй вкладке, это ошибка? - PullRequest
0 голосов
/ 04 июня 2018

Это мой код MainWindow, который содержит 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>

А вот код:

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

Поскольку элемент управления local:View встроен внутрь "Item1 ", затем View_Loaded будет вызван дважды (один раз, когда Окно запускается, другой, когда" Item1 "подходит к просмотру). Между ними не было вызвано событие Unloaded.

Согласно Same Bent из Microsoft , это явно ошибка

Я рекомендую вам сообщать об ошибках о вещах, которые явно ошибочны, например,

  • Не загруженные события без соответствия Loaded
  • Два загруженных события без вмешательства Unloaded
  • Элемент хорошо виден и активен, но не загружен

Или это так?Может ли Microsoft сделать такую ​​элементарную ошибку с таким контролем?Как это объяснить?

1 Ответ

0 голосов
/ 04 июня 2018

Я не уверен, что это ошибка, но на самом деле есть несколько элементов управления в поведении WPF, подобных этому.

Элементы управления, которые будут повышать Loaded дважды без Unloaded:

  • TabControl
  • Popup

Когда элементы управления добавляются в визуальное дерево, событие Loaded будет вызываться для всех его дочерних элементов.И когда ребенок показывает или открывает, событие Loaded снова поднимется.Когда ребенок закрывается, событие Unloaded будет инициировано один раз.И когда TabControl или Popup был удален из визуального дерева, событие Unloaded будет вызвано снова.


Когда элемент управления табуляции добавляется в визуальное дерево:

  • TabControl Loaded -> TabItem0 Loaded -> TabItem1 Loaded ->…

Когда вкладка управления изменила вкладку:

  • Old Active Tab Unloaded-> New Active Tab Loaded

Это означает, что все TabItem s будут Loaded дважды и Unloaded дважды.

Popup ведет себя аналогичным образом.

При добавлении всплывающего окна в визуальное дерево:

  • Popup Loaded -> Child Loaded

При открытии всплывающего окна:

  • Child Loaded

Когда всплывающее окно закрыто:

  • Child Unloaded

Когда всплывающее окно удаленоиз визуального дерева:

  • Popup Unloaded

Но если всплывающее окно открывается и удаляется из визуального дерева:

  • Popup Unload -> Child Unloaded (Это может быть не очень ожидаемым.)

На самом деле, я считаю, что в WPF есть много ошибок.Я и мои друзья публикуем их на GitHub:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...