2010-01-19 47 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

相關問題