Почему закрытие последнего дочернего окна сводит к минимуму его родительское окно?
У меня есть следующее простое приложение 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;
};
но я не хочу использовать такой хак, и я хочу понять, почему эта проблема возникает.
Почему это происходит?
Ответы
Ответ 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 обладает этой функциональностью!