tags:

views:

233

answers:

3

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.

+2  A: 

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.

serhio
Ok, but is this a bug in .NET framework? Looks like this exception was intended to be thrown in ShowDialog, not in Show.
Doc Brown
yes, this can be interpreted as a bug. so you will need to disable the form AFTER Show() ing it.
serhio
Thanks for supplying the bug report to MS!
Doc Brown
+1  A: 

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

Chris Haas
+2  A: 

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.

Hans Passant
That's what I thought, too. Since fixing this bug may change the behaviour of existing programs, I suspect MS will never fix this.
Doc Brown
MS Connect: https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=525755
serhio
Don't bother, they don't fix these kind of bugz anymore. Anyhoo, the workaround is simple.
Hans Passant