代码之家  ›  专栏  ›  技术社区  ›  Doc Brown

windows.forms,以非模式状态显示禁用的窗体

  •  3
  • Doc Brown  · 技术社区  · 15 年前

    我在非模态状态下无法显示禁用的窗体。下面是示例代码:

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

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

    编辑:谢谢你的快速回答。似乎我们确实在框架中发现了一个bug。尽管有你的建议,我还是会坚持我的解决方案,因为在“显示”后禁用表单会给用户带来难看的可见效果。

    3 回复  |  直到 15 年前
        1
  •  1
  •   Chris Haas    15 年前

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

        2
  •  4
  •   Hans Passant    15 年前

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

        3
  •  3
  •   serhio    15 年前

    从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 宣布。