问题描述
如果我将一个非模态窗口设置为父窗口的子窗口,方法是将该窗口的Owner属性设置为父窗口,然后从此子窗口中显示一个MessageBox
,如果我关闭子窗口,则父窗口将失去焦点。 如果Windows资源管理器或另一个应用程序处于打开状态,则此应用程序将获取焦点并隐藏我的主窗口。
这似乎是一个已知的问题,我在另一个论坛上看到过,但我没有看到好的解决方案。 在OnDeactivate
中将所有者设置为null不是选项。 在显示MessageBox
之前将所有者设置为null并在之后重置也没有帮助。 在OnClosed
事件中将所有者设置为null也没有帮助。
找到的简单解决方案
如果您遇到与我描述的相同的问题,请在所有子窗口的OnClosing
中放置以下代码。
void OnClosing(System.ComponentModel.CancelEventArgs e)
{
base.OnClosing(e);
if (null != Owner) {
Owner.Activate();
}
// ....
}
该逻辑可跟随任何进一步的处理逻辑,甚至容忍打开MessageBoxes
。
示例代码
问题似乎比我想象的要严重得多。如果打开消息框并关闭子窗口,则以下示例将删除父窗口的焦点(将代码复制到窗口的加载事件处理程序中)。
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();
此外,这个例子还会打破焦点链:
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
触发在关闭后将焦点给予父级,或者手动在关闭时强制将焦点给予父级,但这些方法看起来都不太干净(而且如果存在更多活动的同一父窗口的 owned 窗口,就会变得更加复杂,我的当前应用程序中就是这种情况)。没有人知道一个简洁的解决方案吗?
资源: MSDN 描述(请参见非模态窗口通过 Show() 打开的说明) MSDN 论坛上的同样问题,但没有适当的解决方案 另请参阅:WPF 应用程序的不稳定焦点