2010-01-19 77 views
3

我在显示非模态状态下禁用窗体时遇到了一些麻烦。下面是示例代码:Windows.Forms,显示非模态状态下的禁用窗体

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

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

编辑:感谢您的快速解答。似乎我们在这里的框架中确实发现了一个错误。尽管有您的建议,但我认为我会继续使用我的解决方案,因为在'显示'给用户带来丑陋的可见效果后禁用该表单。

+0

这或称为显示(this),然后禁用它是我能想到的唯一两种方式 – 2010-01-19 16:21:20

+0

我的IDE说:“未启用的窗体不能显示为模式对话框。将窗体的enabled属性设置为true然后打电话给Show。“ – 2010-01-19 16:22:02

+0

@Chris:我认为使用'Show'会在非模态状态下显示Form,只有ShowDialog会在模态状态下执行它,所以在哪里捕捉? – 2010-01-19 16:24:07

回答

1

或者拨打电话Show(this)然后禁用它是我能想到的唯一两种方式。

3

从微软的参考来源:

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声明。

+0

好吧,但这是.NET框架中的错误吗?看起来这个异常是在ShowDialog中抛出的,而不是在Show中抛出。 – 2010-01-19 16:21:55

+0

是的,这可以解释为一个错误。因此您需要禁用AFTER Show()的表单。 – serhio 2010-01-19 16:49:43

+0

感谢您向MS提供错误报告! – 2010-01-20 14:55:12

4

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

+0

这就是我的想法。由于修复这个bug可能会改变现有程序的行为,我怀疑MS永远不会解决这个问题。 – 2010-01-19 16:59:45

+0

MS Connect:https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=525755 – serhio 2010-01-19 17:24:07

+0

不要打扰,他们不会修复这些bugz了。 Anyhoo,解决方法很简单。 – 2010-01-19 17:34:21

相关问题