我以表格A開頭
表格A呼叫表格B,帶有.Show()
。無模式表格呼叫模態表格阻止初始表格
因此,表單A和表單B都可以訪問。
現在,我不想形成B調用形式C與ShowDialog()
,因爲我不希望形式B可訪問,而形式C是開放的。
問題是:表單A無法訪問。
在這種情況下,我怎樣才能使窗體A和窗體C都可訪問,但不能使用窗體B?
我以表格A開頭
表格A呼叫表格B,帶有.Show()
。無模式表格呼叫模態表格阻止初始表格
因此,表單A和表單B都可以訪問。
現在,我不想形成B調用形式C與ShowDialog()
,因爲我不希望形式B可訪問,而形式C是開放的。
問題是:表單A無法訪問。
在這種情況下,我怎樣才能使窗體A和窗體C都可訪問,但不能使用窗體B?
這是完全由設計,對話框禁用所有在應用程序中的窗口。有一個很好的理由,在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的使用足夠醜陋。
模態窗口是這樣的,他們需要用戶輸入和解僱,然後才允許她回到其他部分的應用程序。因此,如果您想讓用戶與多個窗口進行交互,則無法使用它們。
您必須通過在顯示窗口C之前禁用窗口B(設置Enabled
至false
)並在窗口C關閉後再次啓用它來手動處理這種情況。
這很清楚爲什麼這是設計。我知道這不是解決方案,它可以幫助我重新設計自己的情況(所有表單都是無模式的,嗚呼!)。謝謝! –
您也可以使用窗體句柄WM_ENABLE並重新啓用它自己。請參閱vasek的答案http://stackoverflow.com/questions/581528/c-sharp-winforms-multiple-top-level-windows-and-showdialog –