为什么关闭最后一个子窗口会最小化其父窗口
本文关键字:窗口 最小化 最后一个 为什么 | 更新日期: 2023-09-27 18:35:17
我有以下简单的 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;
};
但我不想使用这样的黑客,我想了解为什么会出现这个问题。
为什么会这样?
WPF未记录的功能(错误)
此错误已在 7 多年前报告给Microsoft。
非模态窗口顶部的模式对话框将主窗口置于底层。
WPF 团队最近已审查此问题,不会 解决此问题,因为此时团队正在关注错误 影响最多数量的 WPF 开发人员。
让我们稍微看一下这个未记录的功能的行为。
它不会最小化,只需在后面一个窗口(在调试模式下,在视觉工作室窗口后面)
证明步骤:
运行此应用程序。
最小化所有其他窗口(例如:Visual Studio 和所有其他窗口)。只在屏幕上保留这三个窗口。
关闭两个子项,父项仍处于
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,则不会发生这种情况。但在许多情况下,这可能不是一种选择。
parentWindow.Topmost = true;
解决方法
在子项 2 关闭时激活父项。
childWindow2.Closed += (a, b) => { parentWindow.Activate(); };
这是因为一旦子窗口与所有者集一起显示,就无法使用父窗口。只需尝试在孩子在屏幕上时访问父窗口,它就不会让您明白我的意思。
如果未指定所有者,则不会发生此行为。
我从来没有弄清楚是什么导致了这种情况的发生!最后,我编写了以下代码,该代码在任何子窗口关闭后调用:
// 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()
为假),则激活父窗口。这不会导致闪烁(例如,主窗口最小化然后最大化。
这不是最好的解决方案。我不会关闭这个问题,希望有人可以解释为什么 WPF 具有此功能!