Karsten
Karsten

Reputation: 1866

How to make a form stay above another

In my .NET application I am showing a form with a "Please wait" message if some task takes a while to tell the user that the program still works. This form has to run in it's own thread since the main thread is the one doing work and therefore busy. I read that one can use Form.Owner for this task, but I don't think that works if the forms run on different threads.

The problem is that the wait form can be hidden behind the main form in which case the user couldn't see it and can't bring it to the front, since it has no task bar button (an it musn't have one).

My question is if it is possible to let the wait form stay above the main form without making it an AlwaysOnTop form (which would stay above ALL windows)?

Upvotes: 0

Views: 1096

Answers (3)

Gosha_Fighten
Gosha_Fighten

Reputation: 3858

You can use the Form.TopMost property for this.

You can also use the following code:

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

bottom - the pointer of the main form, top - the pointer of the wait form. To get a pointer, use Form.Handle property. And call the SetZOrder via the BeginInvoke method of the parent form.

Upvotes: 1

snowcold
snowcold

Reputation: 71

You could use the Form.ShowDialog(IWin32Window)

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

Upvotes: 1

Peter Duniho
Peter Duniho

Reputation: 70652

Your main thread should not be doing work. It should be handling UI and nothing else.

The right way to do this is to perform any and all time-consuming work in an asynchronous manner (e.g. in a separate thread), and keeping all of your user interface in the main thread. Then you can simply show the "Please wait" message form by calling the Form.ShowDialog() method. This will force focus to that dialog and keep it on top of its parent form (don't forget to pass the parent form reference to the ShowDialog() method).

Without a code example, I can't say exactly how this would look in your specific scenario. But the general idea looks something like this:

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

Upvotes: 2

Related Questions