线程中最热门的形式?

问题描述 投票:0回答:3

我正在使用以下代码在新线程中打开表单:

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();
}

但是新创建的表单不是 TopMost,即使我将其设置为 true。

如何在线程 TopMost 中制作表单?

c# winforms multithreading forms topmost
3个回答
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 形式。


2
投票

我自己也遇到了这个问题。看起来,如果表单有

Owner
,那么
TopMost
就会按预期工作。但是,如果拥有的表单是在另一个线程上创建的,则设置起来有点“棘手”。这是我用过的: 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
投票

Invoke 方法用于封送来自不同线程的对 UI 线程的调用。当您使用 Invoke 时,它本质上是安排要在 UI 线程上执行的方法,确保遵守线程安全规则。

这就是您需要使用 Invoke 的原因:

    线程亲和性
  • :UI 控件只能由创建它们的线程访问。 Invoke 确保该方法在 UI 线程上执行。
  • 防止异常
  • :如果不使用 Invoke,尝试从不同线程更新 UI 将引发异常。
  • 安全更新
  • :Invoke 允许从工作线程对 UI 控件进行安全、同步更新。
  • 注意:虽然表单本身是在另一个线程中创建的,但UI线程仍然用于显示表单。

不要直接调用 ShowDialog,而是尝试使用 this.Invoke 来获得表单的所有权。

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(); }); }

	
© www.soinside.com 2019 - 2024. All rights reserved.