Почему закрытие последнего дочернего окна сводит к минимуму его родительское окно? - программирование
Подтвердить что ты не робот

Почему закрытие последнего дочернего окна сводит к минимуму его родительское окно?

У меня есть следующее простое приложение wpf:

App.xaml:

<Application x:Class="TestWpf2.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
</Application>

App.xaml.cs:

public partial class App : Application
{
    protected override void OnStartup(StartupEventArgs e)
    {
        var parentWindow = new Window();
        parentWindow.Show();

        var childWindow1 = new Window { Owner = parentWindow };
        childWindow1.Show();

        var childWindow2 = new Window { Owner = parentWindow };
        childWindow2.Show();
    }
}

Приложение вызывает появление 3 окон на экране. Если вы запустите приложение и закройте два дочерних окна, родительское окно будет сведено к минимуму на панели задач. Если вы закомментируете childWindow2.show(), запустите приложение и закройте одно дочернее окно, родительское окно не будет сведено к минимуму на панели задач.

Я могу добавить следующий код для решения этой проблемы:

childWindow1.Closing += delegate(object sender, CancelEventArgs ex)
{
    (sender as Window).Owner = null;
};

но я не хочу использовать такой хак, и я хочу понять, почему эта проблема возникает.

Почему это происходит?

4b9b3361

Ответ 1

Это недокументированная функция WPF (ошибка)

Эта ошибка была отправлена ​​Microsoft более 7 лет назад.

Модальный диалог поверх немодального окна отправляет главное окно назад.

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

Посмотрите на поведение этой недокументированной функции немного.

Он не сводит к минимуму, просто зайдите за одно окно (в режиме отладки, за окном визуальной студии)

Шаги для доказательства:

  • Запустите это приложение.

  • Свернуть все остальные окна (например: визуальная студия и все остальные окна). Держите только эти три окна на экране.

  • Закройте обоих дочерних элементов, родитель все еще находится в Normal Состояние

Протестируйте этот код для дальнейшего доказательства: StateChange не будет срабатывать.

        protected override void OnStartup(StartupEventArgs e)
        {
            var parentWindow = new Window() { Title = "Parent" };
            parentWindow.StateChanged += (sender, ep)=>
            {
                var state = ((Window)sender).WindowState;
            };
            parentWindow.Show();

            var childWindow1 = new Window { Owner = parentWindow, Title = "Child1" };
            childWindow1.Show();

            var childWindow2 = new Window { Owner = parentWindow, Title = "Child2" };
            childWindow2.Show();
        }

Быть TopMost предотвратить это.

Если родительское окно - TopMost, этого не произойдет. Но во многих случаях это может быть не вариант.

parentWindow.Topmost = true;

Обход

Активируйте родителя при закрытии child2.

childWindow2.Closed += (a, b) => { parentWindow.Activate(); };

Ответ 2

Это связано с тем, что вы не можете использовать родительское окно, когда дочернее окно отображается с помощью набора Owner. Просто попробуйте обратиться к родительскому окну, пока ребенок находится на экране, и он не позволит вам увидеть, что я имею в виду.

Если вы не укажете владельца, этого поведения не произойдет.

Ответ 3

Я никогда не разбирался в том, что вызывает это! В конце концов, я написал этот код, который вызывается после закрытия любого дочернего окна:

// App inherits from Application, and has a Window property called MainWindow
// and a List<Window> property called OpenWindows.
if (!App.OpenWindows.Any())
    App.ParentWindow.Activate();

Итак, если последнее дочернее окно закрыто (создание App.OpenWindows.Any() false), родительское окно активируется. Это не приводит к мерцанию (например, главное окно минимизирует, а затем максимизирует).

Это не лучшее решение. Я не буду закрывать этот вопрос в надежде, что кто-то сможет объяснить, почему WPF обладает этой функциональностью!