【发布时间】:2011-03-09 19:27:08
【问题描述】:
问题描述
如果我通过将窗口的所有者设置为父窗口来将非模态窗口设置为子窗口,然后在此子窗口中显示MessageBox,如果我关闭父窗口,父窗口将失去焦点子窗口。如果 Windows 资源管理器或其他应用程序打开,此应用程序将获得焦点,我的主窗口将被隐藏。
这似乎是一个已知问题,因为我在另一个 newsgroups 中看到了它,但我没有看到一个好的解决方案。在OnDeactivate 中将所有者设置为空不是一种选择。在将 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 或者手动强制关闭父级的焦点可能是可行的,但这在我看来非常不干净(而且还有一点如果同一个父级有更多的活动拥有的窗口,就像我在当前的应用程序中那样)。
没有人知道一个巧妙的解决方案吗?
资源
MSDN Description(请参阅下面的备注打开调用 Show() 的非模态窗口)
【问题讨论】: