【问题标题】:Top level window in WinFormsWinForms 中的顶级窗口
【发布时间】:2016-01-30 23:52:13
【问题描述】:

对于 WinForms 有很多关于此的问题,但我还没有看到提到以下场景的问题。

我有三种形式:

(X) Main  
(Y) Basket for drag and drop that needs to be on top  
(Z) Some other dialog form  

X is the main form running the message loop.
X holds a reference to Y and calls it's Show() method on load.
X then calls Z.ShowDialog(Z).

现在 Y 在 Z 关闭之前无法访问。

我可以理解为什么(不是真的)。有没有办法让 Y 保持浮动,因为最终用户需要独立于任何其他应用程序表单与之交互。

【问题讨论】:

  • 让 X 调用 Show() 而不是 ShowDialog()?

标签: c# .net winforms dialog toplevel


【解决方案1】:

如果您想使用ShowDialog 显示一个窗口,但又不希望它阻塞主窗体以外的其他窗口,您可以在单独的线程中打开其他窗口。例如:

private void ShowY_Click(object sender, EventArgs e)
{
    //It doesn't block any form in main UI thread
    //If you also need it to be always on top, set y.TopMost=true;

    Task.Run(() =>
    {
        var y = new YForm();
        y.TopMost = true;
        y.ShowDialog();
    });
}

private void ShowZ_Click(object sender, EventArgs e)
{
    //It only blocks the forms of main UI thread

    var z = new ZForm();
    z.ShowDialog();
}

【讨论】:

  • 那会创建第二个 UI 线程,不是吗?单个进程中的多个 UI 线程可能会导致严重的问题,AFAIK。
  • @ThomasWeller 同意,一般来说,开发人员最好依赖owned windows 或简单的非模态窗口并处理确定/取消按钮事件。
【解决方案2】:

在 x 中,你可以放一个 y.TopMost = true;在 Z.ShowDialog() 之后。这会将 y 放在顶部。然后,如果您希望其他形式起作用,您可以输入 y.TopMost = false;在 y.TopMost = true 之后;这会将窗口置于顶部,但稍后允许其他表单覆盖它。

或者,如果问题是一个表单被放在另一个表单之上,那么您可以在表单的属性中更改其中一个表单的起始位置。

【讨论】:

    【解决方案3】:

    您可以将主窗体 (X) 更改为 MDI 容器窗体 (IsMdiContainer = true)。然后您可以将剩余的表单作为子表单添加到 X。然后使用 Show 方法而不是 ShowDialog 来加载它们。这样所有子窗体都会在容器内浮动。

    您可以像这样将子表单添加到 X:

    ChildForm Y = new ChildForm();
    Y.MdiParent = this //X is the parent form
    Y.Show();
    

    【讨论】:

      猜你喜欢
      • 2019-09-27
      • 1970-01-01
      • 1970-01-01
      • 2015-05-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多