TopMost form in a thread?
Asked Answered
C

3

9

I am using the following code to open a form in a new thread:

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

But the newly created form isn't TopMost even though I set it to true.

How can I make a form in a thread TopMost ?

Clave answered 20/1, 2011 at 6:52 Comment(0)
F
5

Usually you don't need another thread, you open the form as usual in modal or non modal mode, if the form needs to do a heavy process then you do the process inside a thread.

Specific to your question one option is to run the form from an Application.Run as described 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);
        }
    }
}

That will launch a new thread with its own message pump and will keep it as a TopMost form.

Florentinoflorenza answered 20/1, 2011 at 7:5 Comment(3)
Ok so that should create a form in a new thread and allow it to become topmost form? I will give it a try ! thxClave
That actually didnt work because if i "Application.Run(_form);" in the new thread it stills is in a new thread and the problem will remain that it wont become topmost, and if i try to start "Application.Run(_form);" without starting a new thread(starting in the main thread) then i get exception " Starting a second message loop on a single thread is not a valid operation."Clave
I modified with a more complete code, it produces the expected result for meFlorentinoflorenza
B
2

Just ran into this problem myself. It seems that if the form has an Owner, then TopMost works as expected. If the owning form was created on another thread, though, it's a little tricky to set. Here's what I used:

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);
Bibliofilm answered 18/8, 2011 at 13:10 Comment(0)
E
-1

Instead of calling ShowDialog directly, try using this.Invoke to gain ownership of the form.

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(); });
}
Echovirus answered 16/6, 2016 at 18:7 Comment(1)
As is your answer is rather uninformative. Consider adding why this might be the solution.Viper

© 2022 - 2024 — McMap. All rights reserved.