![](/img/trans.png)
[英]Show form that showDialog from mainForm won't block it, but closing mainForm will close it
[英]Show and ShowDialog won't work
它與我以前見過的任何東西都不一樣。
當我調用(new System.Windows.Forms.Form())。ShowDialog()時,表單會顯示一毫秒或者其他東西然后消失。
我跟蹤了電話並得到了:
System.Windows.Forms.Form.Dispose
System.ComponentModel.Component.Dispose
System.Windows.Forms.Application.ThreadWindows.Dispose
System.Windows.Forms.Application.ThreadContext.DisposeThreadWindows
System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop
System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner
System.Windows.Forms.Application.ThreadContext.RunMessageLoop
System.Windows.Forms.Form.ShowDialog Esfand.Program.Main C#
我已經嘗試過任何解決此問題的方法。
雖然我在嘗試顯示此表單之前已經顯示了登錄表單。
我不認為登錄表單上有任何特殊內容(通常無聊的東西,連接到服務器,發送憑據,接收數據)。
我正在使用表單的主線程。 我具有消息傳遞和消息循環的經驗。 我已經在登錄表單中使用了線程。
編輯:澄清Cody Gray的建議:
這就是我在void Main(string[])
:
LoginForm login = new LoginForm ();
login.ShowDialog ();//works
if (login.DialogResult == DialogResult.OK)
{
MainForm f = new MainForm ();
f.ShowDialog ();//won't work
}
在新線程中創建和顯示MainForm使得所有內容都重新開始工作。但是每個表單上都會出現隨機錯誤,導致此解決方案不夠好。
編輯2:
FormClosing事件甚至不會觸發。
System.Windows.Forms.Form A;
A = new Form();
A.FormClosing += new FormClosingEventHandler((sender, e) => { System.Diagnostics.Debugger.Break();/*won't work. tried Breakpoints and other stuff too*/ });
A.ShowDialog();
編輯3:HandleDestroyed事件堆棧跟蹤:
> Esfand.exe!Esfand.Program.Main.AnonymousMethod__1(object sender = {System.Windows.Forms.Form}, System.EventArgs e = {System.EventArgs}) Line 50 + 0x6 bytes C#
System.Windows.Forms.dll!System.Windows.Forms.Control.OnHandleDestroyed(System.EventArgs e) + 0x9e bytes
System.Windows.Forms.dll!System.Windows.Forms.Form.OnHandleDestroyed(System.EventArgs e) + 0x13 bytes
System.Windows.Forms.dll!System.Windows.Forms.Control.WmDestroy(ref System.Windows.Forms.Message m) + 0x54 bytes
System.Windows.Forms.dll!System.Windows.Forms.Control.WndProc(ref System.Windows.Forms.Message m) + 0x547 bytes
System.Windows.Forms.dll!System.Windows.Forms.Form.WndProc(ref System.Windows.Forms.Message m) + 0x6d bytes
System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.DebuggableCallback(System.IntPtr hWnd, int msg = 2, System.IntPtr wparam, System.IntPtr lparam) + 0x15e bytes
[Native to Managed Transition]
[Managed to Native Transition]
System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.DestroyHandle() + 0xf7 bytes
System.Windows.Forms.dll!System.Windows.Forms.Control.DestroyHandle() + 0x3e3 bytes
System.Windows.Forms.dll!System.Windows.Forms.Control.Dispose(bool disposing) + 0x347 bytes
System.Windows.Forms.dll!System.Windows.Forms.ContainerControl.Dispose(bool disposing) + 0x19 bytes
System.Windows.Forms.dll!System.Windows.Forms.Form.Dispose(bool disposing) + 0x26a bytes
System.dll!System.ComponentModel.Component.Dispose() + 0x1b bytes
System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadWindows.Dispose() + 0xb3 bytes
System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.DisposeThreadWindows() + 0x12d bytes
System.Windows.Forms.dll!System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(System.IntPtr dwComponentID, int reason, int pvLoopData) + 0x58e bytes
System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(int reason = 4, System.Windows.Forms.ApplicationContext context = {System.Windows.Forms.Application.ModalApplicationContext}) + 0x593 bytes
System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoop(int reason, System.Windows.Forms.ApplicationContext context) + 0x81 bytes
System.Windows.Forms.dll!System.Windows.Forms.Form.ShowDialog(System.Windows.Forms.IWin32Window owner) + 0x765 bytes
Esfand.exe!Esfand.Program.Main(string[] a = {string[0]}) Line 51 + 0x10 bytes C#
這件事正在使程序中的每個表單都引發唯一錯誤(例如,“無法注冊拖放事件處理程序”)
這是代碼中核心問題的有力暗示。 當您具有AllowDrop屬性設置為true的任何控件時,將調用RegisterDragDrop()本機函數。 在創建表單的本機窗口時調用它。 不幸的是,如果您擁有64位版本的Windows並且強制程序以32位模式運行,那么引發任何異常都是非常糟糕的時間。 這個答案的主題。
RegisterDragDrop()失敗的理由很少。 但是一個。 我們已經可以從你的代碼片斷中告訴你,你一直在修改Program.cs。 樣板版本如下所示:
static class Program {
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread] // <=== Here!!!
static void Main() {
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
我把Big Arrow放在重要的代碼行上。 [STAThread]屬性在任何GUI程序中都是必不可少的。 它告訴CLR應該初始化COM並將程序的主線程配置為單線程單元。 公寓是一個非常重要的COM實現細節,其范圍超出了這個答案。 如果缺少該屬性,則程序的主線程將加入多線程單元MTA。 惡意代碼不安全的地方,例如拖放,剪貼板和外殼對話框。
忘記使用該屬性可能會導致令人困惑的異常。 當您的開發機器啟動64位版本的Vista或Win7時,尤其糟糕的是,Windows版本的出現在關鍵時刻出現異常的麻煩,如鏈接的答案所述。
Program.Main()方法的正確版本沒有此問題,否則使用建議的做法:
[STAThread] // <=== Don't forget this
static void Main() {
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
using (var login = new LoginForm()) {
if (login.ShowDialog() != DialogResult.OK) return;
}
Application.Run(new MainForm());
}
嘗試檢查是否拋出線程異常錯誤。 檢查您是否在Application_ThreadException事件中看到任何內容。
static void Main()
{
Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
try
{
//Your existing code
}
catch (Exception ex)
{
}
}
private static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
{
}
編輯:另一種選擇是明確將MainForm設置為正在創建的newForm的所有者。
newForm.ShowDialog(MainForm);
我有一種感覺,默認情況下,所有者被設置為您的登錄表單已關閉,這是自動關閉您的新表單
當事件隊列上有WM_QUIT消息時,看起來IMsoComponentManager.FPushMessageLoopP()
將調用Application.ThreadContext.DisposeThreadWindows()
。
您是否在LoginForm
的按鈕事件處理程序中發布了退出消息?
嘗試將表單定義為類成員。 不在函數內部。
你的Main
方法看起來很奇怪。 我想你錯過了對Application.Run()
的調用。 由於您不希望應用程序在登錄表單關閉后立即退出,因此您可能需要一個ApplicationContext
。 MSDN有一個示例: http : //msdn.microsoft.com/en-us/library/ms157901.aspx
另一種可能性是使用不可見的形式調用Application.Run()
作為參數,然后顯示其他形式(並且在應用程序退出之前永遠不會關閉),但在我看來這是一個相當丑陋的黑客。
我的理解是表單需要在應用程序上下文中運行。
我以下列方式繼承了一些代碼,這些代碼從Main上下文啟動了幾種形式:
var form1 = Form1();
Application.Run(form1);
// form returns, check public method form.ButtonPushed etc
if (form.Button1Pushed)
{
var form2 = Form2();
Application.Run(form2);
}
這將成功啟動幾種形式。
感覺不像是一種非常優雅的做事方式,但它可以工作...
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.