WPF 应用程序完全失去对窗口关闭的关注 [英] WPF App loses focus completely on window close

查看:25
本文介绍了WPF 应用程序完全失去对窗口关闭的关注的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题描述

如果我通过将窗口的所有者设置为父窗口来将非模态窗口作为子窗口,然后从该子窗口中显示一个MessageBox,则父窗口将丢失如果我关闭子窗口,则聚焦.如果 Windows 资源管理器或其他应用程序打开,此应用程序将获得焦点,而我的主窗口将被隐藏.

If I make a non-modal window as a child window through setting the Owner of the window to a parent window, and then show a MessageBox from within this child window, the parent window will lose focus if I close the child window. If windows explorer or another app is open, this app will get the focus and my main window will be hidden.

这似乎是一个已知问题,因为我在另一个新闻组,但我没有看到好的解决方案.在 OnDeactivate 中将所有者设置为 null 不是一个选项.在显示 MessageBox 之前将所有者设置为 null 并在此之后重置无济于事.在 OnClosed 事件中将所有者设置为 null 也无济于事.

This seems to be a known problem as I saw it in another newsgroups, but I don’t have seen a good solution. Setting the owner to null in OnDeactivate is not an option. Setting the owner before showing the MessageBox to null and resetting after that doesn’t help. Setting the owner to null in the OnClosed event does also not help.

找到简单的解决方案

如果您遇到与我描述的相同的问题,请将以下代码放在所有子窗口的 OnClosing 中.

If you experience the same problem as I have described, put the following code in the OnClosing of all child windows.

void OnClosing(System.ComponentModel.CancelEventArgs e)
{
    base.OnClosing(e);
    if (null != Owner) {
        Owner.Activate();
    }
    // ....
}

它可以跟随任何进一步的处理逻辑,甚至允许打开MessageBoxes.

It can be followed by any further processing logic, even opening MessageBoxes is tolerated.

示例代码

问题似乎比我想象的要大得多.下面的示例将在打开消息框并关闭子窗口时移除父窗口的焦点(将代码复制到窗口的已加载事件处理程序中).

The issue seems to be much bigger as I thought. The following example will remove focus of the parent window if the message box will be opened and the the child window will be closed (Copy the code into a loaded event-handler of a Window).

Window firstChildWindow = new Window() {
    Title = "Floating Window", Width = 100, Height = 70
};
firstChildWindow.Owner = Window.GetWindow(this);    
Button button = new Button() { Content="MessageBox"};
button.Click += delegate { MessageBox.Show("Klicking her breaks the focus-chain."); };
firstChildWindow.Content = button;
firstChildWindow.Show();

这个例子也打破了焦点链:

Also this example breaks the focus-chain:

Window firstChildWindow = new Window() {
    Title = "Floating Window", Width = 100, Height = 70
};
firstChildWindow.Owner = Window.GetWindow(this);
firstChildWindow.Show();    
Window secondChildWindow = new Window() { Title="Second Window", Width=100, Height=70};
secondChildWindow.Content = new TextBlock() { Text="SecondWindow"};
secondChildWindow.Owner = firstChildWindow;
secondChildWindow.Show();

有人解决了这个问题.我考虑在关闭后使用 Dispatcher 或 DispachterTimer 触发将焦点转移给父级的黑客,或者在关闭时手动将焦点强制给父级可能会起作用,但这在我看来都很不干净(如果同一个父级有更多活动的自有窗口,这也有点复杂,就像我在当前的应用程序中那样).

Has someone a resolution for this problem. I think about a hack to trigger giving focus to the parent after closing, with Dispatcher or DispachterTimer or perhaps it would be work to manually force focus to the parent on closed but this all seems to me very unclean (and is also a little complicated if there are more active owned windows of the same parent, as I have in my current app).

没有人知道一个巧妙的解决方案吗?

No one knows a neat solution to this?

资源

MSDN 说明(见下非模态窗口的备注打开调用 Show())

MSDN Description (see under remarks for non modal windows opened calling Show())

同样的问题MSDN论坛没有合适的解决方案

另请参阅:WPF 应用程序的焦点不稳定

推荐答案

这里最有可能发生的情况是您有两个独立的顶级窗口并关闭了其中一个.这有时会导致焦点跳转到另一个应用程序.

What most likely happened here is you have two independent top level windows and closed one of them. This will sometimes cause focus to jump to another application.

如果一个窗口拥有第二个,而后者又拥有第三个,也会发生这种情况.Win32 API 中可能存在 BUG,但它一直伴随着我们,祝你好运修复它.

This also happens if one windows owns a second, which in turn owns a third. Probable BUG in the Win32 API but its been with us forever so good luck getting it fixed.

解决方法是在孙子的 Closing 事件中手动将焦点交还给子子.但在这种情况下,孙子是一个消息框,所以你不能这样做.最简单的方法是将消息框拥有给父级.下一个最简单的方法是制作自己的消息框控件.

The workaround is to manually hand focus back to child in the Closing event of the grandchild. But in this case, grandchild is a messagebox so you can't do that. The easiest thing to do is to own messagebox to parent. The next easiest is to make your own messagebox control.

这篇关于WPF 应用程序完全失去对窗口关闭的关注的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆