2012-11-26 22 views
0

我以表格A開頭
表格A呼叫表格B,帶有.Show()無模式表格呼叫模態表格阻止初始表格

因此,表單A和表單B都可以訪問。

現在,我不想形成B調用形式C與ShowDialog(),因爲我不希望形式B可訪問,而形式C是開放的。

問題是:表單A無法訪問。

在這種情況下,我怎樣才能使窗體A和窗體C都可訪問,但不能使用窗體B?

回答

3

這是完全由設計,對話框禁用所有在應用程序中的窗口。有一個很好的理由,在this answer概述。

簡而言之,嚴重故障情況是用戶可以使用表單A中的命令創建表單B的另一個實例,該實例未禁用。它允許你再次顯示C,現在你有兩個對話框顯示。

你可能會好奇地發現,這絕對不會發生在你的情況。沒關係,但是你必須撤銷ShowDialog()的功能。這需要體操,你必須重新啓用EnableWindow()來重新啓用表單A實例。但是你必須在ShowDialog()調用之後但在結束之前這麼做。你可以通過在UI線程上使用Control.BeginInvoke()來做些什麼。該trickorama看起來是這樣的:

private void ShowDialogButton_Click(object sender, EventArgs e) { 
     using (var dlg = new Form3()) { 
      // Find the main form instance 
      var main = Application.OpenForms.OfType<Form1>().Single(); 
      this.BeginInvoke(new Action(() => { 
       EnableWindow(main.Handle, true); 
      })); 
      if (dlg.ShowDialog(this) == DialogResult.OK) { 
       // etc.. 
      } 
     } 
    } 

    [System.Runtime.InteropServices.DllImport("user32.dll")] 
    private static extern bool EnableWindow(IntPtr handle, bool enable); 

你也可以把所示的事件處理程序對話框的的EnableWindow()調用,因此避免了使用的BeginInvoke伎倆。但這種方式更普遍,對話框通常不應該知道其他窗口在應用程序中運行的是什麼。此代碼中Form1的使用足夠醜陋。

+0

這很清楚爲什麼這是設計。我知道這不是解決方案,它可以幫助我重新設計自己的情況(所有表單都是無模式的,嗚呼!)。謝謝! –

+0

您也可以使用窗體句柄WM_ENABLE並重新啓用它自己。請參閱vasek的答案http://stackoverflow.com/questions/581528/c-sharp-winforms-multiple-top-level-windows-and-showdialog –

0

模態窗口是這樣的,他們需要用戶輸入和解僱,然後才允許她回到其他部分的應用程序。因此,如果您想讓用戶與多個窗口進行交互,則無法使用它們。

您必須通過在顯示窗口C之前禁用窗口B(設置Enabledfalse)並在窗口C關閉後再次啓用它來手動處理這種情況。