激活主窗口时,可以看到辅助无模式窗口

时间:2016-03-15 00:48:20

标签: c# .net winforms

我有一个Winforms应用程序,主窗体可以创建多个辅助通知窗口。这些辅助窗口没有所有者并且是无模式的,因为我希望主窗体能够位于它们之上。它们也没有显示在任务栏中(ShownInTaskbar = False)。

现在,如果主窗口被最小化(或者其他应用程序被置于其上),并且我在任务栏中单击我的应用程序图标,我希望所有辅助窗口也显示(但是主要如果它们重叠,它们顶部的窗口)。所以,我希望我的主窗口位于最顶层,后面的辅助窗口以及THEM背后的任何其他应用程序。

为了实现这一点,我在内存中保留了这些辅助窗口的列表。我编写了以下事件处理程序来显示辅助窗口:

private void SmgWfMainForm_Activated(object sender, EventArgs e)
{
    foreach(SecondaryWindow sw in _secondaryWindows)
    {
        sw.BringToFront();
    }
    this.BringToFront();
}

不幸的是,这不起作用。最后调用this.BringToFront()会导致Activated事件处理程序再次触发,并且处理程序会在无限循环中一遍又一遍地重复启动。因为这个原因,我永远无法与我的主要形式互动。如果我省略了那个电话,最后一个辅助窗口会得到焦点,如果我点击我的主窗体,事件就会触发,辅助窗口再次位于主窗体之上,我也有同样的问题。

关于如何解决此问题的任何想法?除了this.BringToFront()之外还有其他什么我可以调用它不会导致Activated事件再次触发吗?或者也许我可以听的其他事件不会被this.BringToFront()触发?

1 个答案:

答案 0 :(得分:0)

您可以使用布尔变量来防止重入:

private bool _activatingFromEvent = false;

protected override void OnActivated(EventArgs evt)
{
  if(_activatingFromEvent)
  {
    // Don't call the event this time
    _activatingFromEvent = false;
    return;
  }
  base.OnActivated(evt);
}

private void SmgWfMainForm_Activated(object sender, EventArgs e)
{
    if(_activatingFromEvent) 
      return;
    _activatingFromEvent = true;
    foreach(SecondaryWindow sw in _secondaryWindows)
    {
        sw.BringToFront();
    }
    this.BringToFront();
}

这可以在不改变太多代码的情况下解决您的直接问题。

编辑 :我现在看到你说你的表格不属于我,所以我猜他们不是有原因的,所以忽略其余的答案。无论如何,我会把它留在这里

另一种做你想做的事情的方法就是让你的辅助表格拥有"拥有"在您的主要表单中(当您展示它们时,将主表单传递到Show方法using this overload,或设置Owner property)。

这有更多的含义,所以如果你想要它们要小心:

  1. 如果您关闭主表单,拥有的表单也会关闭
  2. 拥有的表单将始终显示在所有者表单
  3. 当您的所有者表单最小化时,所有拥有的表单都会被隐藏(并且在还原时会再次显示)
  4. 如果这对你有用,你最好拥有表格