Doc Brown
Doc Brown

Reputation: 20044

Windows.Forms, showing a disabled form in non-modal state

I have some trouble showing a disabled Form in non-modal state. Here is the example code:

public partial class Form1 : Form
{
    // ....
    private void button1_Click(object sender, EventArgs e)
    {
        try
        {
            Form2 form = new Form2();
            form.Enabled = false;
            form.Show();    // works, but form has no owner
            // form.Show(this); // gives an System.InvalidOperationException
            // ...
            // ... my program here shows a message box, ask user for something
            // ... while 'form' is shown in the background 
            form.Close();
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }

    }
}

Any idea why Show() (without parameter) works, but Show(this) gives an exception? In my scenario, form must know its owner to be shown correctly, so I can do the following:

            form.Enabled = false;
            form.Owner=this;
            form.Show();

but is this really a good solution?

EDIT: Thanks for the quick answers. Seems that we really found a bug in the framework here. In spite of your suggestions, I think I will keep with my solution, since disabling the form after the 'Show' gives an ugly visible effect to the user.

Upvotes: 4

Views: 4511

Answers (3)

serhio
serhio

Reputation: 28586

From Microsoft's reference source:

public void Show(IWin32Window owner)
{
    if (owner == this)
    {
        throw new InvalidOperationException(SR.GetString("OwnsSelfOrOwner", new object[] { "Show" }));
    }
    if (base.Visible)
    {
        throw new InvalidOperationException(SR.GetString("ShowDialogOnVisible", new object[] { "Show" }));
    }

    // Here!!!
    if (!base.Enabled)
    {
        throw new InvalidOperationException(SR.GetString("ShowDialogOnDisabled", new object[] { "Show" }));
    }

    if (!this.TopLevel)
    {
        throw new InvalidOperationException(SR.GetString("ShowDialogOnNonTopLevel", new object[] { "Show" }));
    }
    if (!SystemInformation.UserInteractive)
    {
        throw new InvalidOperationException(SR.GetString("CantShowModalOnNonInteractive"));
    }
    if (((owner != null) && ((((int) UnsafeNativeMethods.GetWindowLong(new HandleRef(owner, Control.GetSafeHandle(owner)), -20)) & 8) == 0)) && (owner is Control))
    {
        owner = ((Control) owner).TopLevelControlInternal;
    }

By the way, there is a MS Connect bug declared.

Upvotes: 4

Hans Passant
Hans Passant

Reputation: 941545

It's a classic cut-and-paste bug. Looks like they copied the code from ShowDialog(), it is indeed invalid to show a disabled form as a dialog. The user would be stuck and can't do anything anymore. But they forgot to remove the test in the Show() method. Just disable it after the Show() call.

Upvotes: 4

Chris Haas
Chris Haas

Reputation: 55427

That or call Show(this) and then disable it are the only two ways that I can think of.

Upvotes: 2

Related Questions