kreddkrikk
kreddkrikk

Reputation: 389

Problems bringing other forms to front in a form's Activated event

I want a MainForm to bring two other separate forms to the front whenever it itself is brought to the front. I am using MainForm's Activated event handler to do this, but bringing the other two forms to the front and returning the focus to MainForm is causing problems:

    private void MainForm_Activated(object sender, EventArgs e)
    {
        tilemapForm.BringToFront();
        tilesetForm.BringToFront();
        this.BringToFront();
        this.Focus();
    }

Whenever this event is triggered, the title bar text of all three forms disappears and the forms flicker like crazy for a couple of seconds before it's done.

Removing this.Focus() fixes it, but then disables MainForm's control box so that minimizing or closing it via the control box becomes impossible. Is there a solution to this dilemma?

Upvotes: 2

Views: 1141

Answers (2)

Mark Hall
Mark Hall

Reputation: 54532

Posting Comment as an answer.

what type of application is this?
How are you creating/showing your two additional forms?

Try adding the Main form as the owning form when you show it using the Show(IWin32Window) method as in tilemapForm.Show(this) if you are creating them in the Main Form. By doing this it will set the Form's Owner Property(you can also do this later by setting the property directly on the Form) which by this quote from the second link will give you the results you are wanting:

When a form is owned by another form, it is closed or hidden with the owner form. For example, consider a form named Form2 that is owned by a form named Form1. If Form1 is closed or minimized, Form2 is also closed or hidden. Owned forms are also never displayed behind their owner form. You can use owned forms for windows such as find and replace windows, which should not disappear when the owner form is selected. To determine the forms that are owned by a parent form, use the OwnedForms property.

Upvotes: 1

Hans Passant
Hans Passant

Reputation: 941217

The Windows window manager has specific counter-measures built-in to stop your program from crashing. Without them, your code would be doomed to crash with this website's name. Since you are writing code that causes the Activate event to be raised again, the recursion will blow the stack and crash your app with StackOverflowException.

One thing it does is completely ignore any attempt to move another window into the foreground when it fires the WM_ACTIVATE message. You discovered this by yourself, so you decided to use the Focus() method to force the window to be activated.

Can't defeat Windows that easily, it has a counter-measure for that as well. It will try up to 32 times to honor your request. Which is what you see, the windows are swapping back-and-forth madly until Windows puts a stop to it when it decides that your program is stuck in an endless loop. These are common programming bugs with a very unhappy outcome, a stack overflow is quite difficult to diagnose.

The workaround is very simple, you want an owned window. An owned window is always displayed on top of its owner and is minimized along with the owner. Very common for tool windows and dialogs.

Use the Show(owner) overload to display these tool windows and delete the Activated event handler.

Upvotes: 1

Related Questions