如何使表格保持在另一个之上

时间:2014-11-23 21:46:25

标签: c# .net windows multithreading winforms

在我的.NET应用程序中,我正在显示一个表格,其中包含"请稍候"消息,如果某个任务需要一段时间告诉用户该程序仍然有效。这个表单必须在它自己的线程中运行,因为主线程正在进行工作,因此很忙。 I read that one can use Form.Owner for this task,但如果表单在不同的主题上运行,我认为不行。

问题在于,等待表单可以隐藏在主表单后面,在这种情况下,用户无法看到它并且无法将其带到前面,因为它没有任务栏按钮(它没有一个。)

我的问题是,是否可以让等待表单保持在主表单之上而不使其成为AlwaysOnTop表单(将保留在所有窗口之上)?

3 个答案:

答案 0 :(得分:2)

你的主线程不应该正常工作。它应该是处理用户界面而不是别的。

执行此操作的正确方法是以异步方式(例如,在单独的线程中)执行任何和所有耗时的工作,并将所有用户界面保留在主线程中。然后,您只需调用Form.ShowDialog()方法即可显示“请稍候”消息表单。这将强制关注该对话框并将其保持在其父窗体之上(不要忘记将父窗体引用传递给ShowDialog()方法)。

如果没有代码示例,我无法确切地说明在您的具体方案中这将是什么样子。但总体思路看起来像这样:

private void button1_Click(object sender, EventArgs e)
{
    using (Form form = MyWaitMessageForm())
    {
        form.Shown += async (sender1, e1) =>
        {
            await Task.Run(() => MyLongRunningWork());
            form.Close();
        }

        form.ShowDialog(this);
    }
}

答案 1 :(得分:1)

您可以使用Form.TopMost属性。

您还可以使用以下代码:

protected void SetZOrder(IntPtr bottom, IntPtr top) {
    const int flags = 0x0002 | 0x0001; 
    NativeMethods.SetWindowPos(bottom, top, 0, 0, 0, 0, flags);
}

bottom - 主窗体的指针,top - 等待窗体的指针。要获取指针,请使用Form.Handle属性。并通过父窗体的BeginInvoke方法调用SetZOrder。

答案 2 :(得分:1)

您可以使用Form.ShowDialog(IWin32Window)

Form1 testDialog = new Form1();
testDialog.ShowDialog(this)