Windows.Forms,显示处于非模态状态的禁用表单

时间:2010-01-19 16:13:53

标签: c# .net winforms

在非模态状态下显示已禁用的表单时遇到一些问题。以下是示例代码:

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

    }
}

知道为什么Show()(没有参数)有效,但Show(this)会出现异常吗?在我的方案中,form必须知道其所有者才能正确显示,因此我可以执行以下操作:

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

但这真的是一个很好的解决方案吗?

编辑:感谢您的快速解答。似乎我们确实在这里找到了框架中的错误。尽管您提出了建议,但我认为我会继续使用我的解决方案,因为在“显示”之后禁用表单会给用户带来难看的可见效果。

3 个答案:

答案 0 :(得分:4)

这是一个经典的剪切和粘贴错误。看起来他们从ShowDialog()复制了代码,将禁用的表单显示为对话框确实无效。用户会被困住,不能再做任何事了。但是他们忘了在Show()方法中删除测试。只需在Show()调用后禁用它。

答案 1 :(得分:3)

来自Microsoft的参考资料来源:

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

顺便说一下,声明了a MS Connect bug

答案 2 :(得分:2)

那个或致电Show(this)然后禁用它是我能想到的唯一两种方式。