WPF App完全关注窗口关闭

HCL*_*HCL 40 .net wpf

问题描述

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

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

找到简单解决方案

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

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

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

例如,代码

我认为这个问题似乎要大得多.如果将打开消息框并关闭子窗口,则以下示例将删除父窗口的焦点(将代码复制到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();
Run Code Online (Sandbox Code Playgroud)

此示例也打破了焦点链:

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();
Run Code Online (Sandbox Code Playgroud)

有人解决这个问题.关于在关闭之后触发给予父母关注的黑客攻击,使用Dispatcher或DispachterTimer,或者也许它可以在关闭时手动将焦点强制给父母,但这一切在我看来都是非常不洁净的(如果正如我在当前的应用程序中那样,父母拥有更多活动拥有的窗口.

没有人知道这个问题的解决方案吗?

资源

MSDN描述(请参阅打开调用Show()打开的非模态窗口的备注)

msdn论坛上的相同问题没有适当的解决方案

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

Jos*_*hua 24

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

如果一个窗口拥有第二个窗口,而后者拥有第三个窗口,则也会发生这种情况.Win32 API中的可能BUG,但它永远和我们在一起,所以很幸运得到它.

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


Mui*_*uis 21

这是一个非常烦人的错误,最常见的解决方案是:

打电话Me.Owner.FocusWindow_UnloadedWindow_Closing事件.

但是仍然无法100%工作,在正确恢复焦点之前,您仍会看到背景窗口闪烁到前景(非常简短).

我发现了一种更好的方法:

Me.Owner.Activate之前Me.Close(或在_Closing事件中)打电话.