2011-01-20 46 views
9

我使用下面的代码在一个新的线程中打开窗体:线程中的TopMost表单?

private void button1_Click(object sender, EventArgs e) 
{ 

    Thread thread = new Thread(ThreadProc); 
    thread.Start(); 
} 


public void ThreadProc() 
{ 

    Form form = new Form(); 
    form.TopMost = true; 
    form.ShowDialog(); 
} 

但新创建的窗体是不是最顶层,即使我将它设置为true。

如何在线程TopMost中创建表单?

回答

5

通常情况下,你不需要另一个线程,如果你需要做一个繁重的过程,然后你在线程内部完成这个过程,你可以照常在模态或非模态模式下打开窗体。

特定于您的问题,一个选项是从Application.Run运行表单,如here所述。

public partial class Form1 : Form 
{ 
    public Form1() 
    { 
     InitializeComponent(); 
    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
     Thread thread = new Thread(ThreadProc); 
     thread.Start(); 
    } 


    public void ThreadProc() 
    { 
     using (Form1 _form = new Form1()) 
     { 
      _form.TopMost = true; 
      Application.Run(_form); 
     } 
    } 
} 

这将启动一个带有自己的消息泵的新线程,并将它保持为TopMost形式。

+0

好了,所以应该在一个新的线程创建一个表单,并使其成为最顶层的形式?我会试一下 ! thx – syncis 2011-01-20 07:31:31

+0

这实际上没有工作,因为如果我“Application.Run(_form);”在新的线程中它仍然是在一个新的线程,问题将保持,它不会成为最顶层,如果我尝试启动“Application.Run(_form);”没有开始一个新的线程(从主线程开始),然后我得到异常“在单个线程上启动第二个消息循环不是一个有效的操作。” – syncis 2011-01-20 17:10:36

+0

我修改了一个更完整的代码,它为我产生了预期的结果 – 2011-01-20 17:34:05

1

自己刚刚遇到了这个问题。看起来如果表格有Owner,那么TopMost按预期工作。如果拥有的表单是在另一个线程上创建的,但它有点tricky to set。下面是我用什么:

var form = new Form(); 

form.Shown += (sender, e) => { 
    Control.CheckForIllegalCrossThreadCalls = false; 
    form.Owner = /* Owning form here */; 
    form.CenterToParent();  // Not necessary 
    Control.CheckForIllegalCrossThreadCalls = true; 

    form.TopMost = true;  // Works now! 
}; 

Application.Run(form); 
-1
private void button1_Click(object sender, EventArgs e) 
{ 

    Thread thread = new Thread(ThreadProc); 
    thread.Start(); 
} 


public void ThreadProc() 
{ 

    Form form = new Form(); 
    form.TopMost = true; 
    this.Invoke((Action)delegate() { form.ShowDialog(); }); 
}