2010-06-18 62 views
37

在構造函數執行時關閉窗體(或簡單地停止它在此階段顯示)是否可能?C#在構造函數中關閉窗體

我有以下代碼:

public partial class MyForm : Form 
{   
    public MyForm() 
    { 
     if (MyFunc()) 
     { 
      this.Close(); 
     } 
    } 
} 

會拋出在主)一個的ObjectDisposedException(這裏:

static void Main() 
    {    
     ... 

     // Following line errors 
     Application.Run(new MyForm()); 
    } 

我已經試過檢查MyForm的像這樣的結果:

static void Main() 
{    
    ... 

    MyForm frm = new MyForm(); 
    if (frm != null) 
    { 
     // Following line errors 
     Application.Run(frm); 
    } 
} 

但這似乎沒有幫助。有誰能告訴我一個解決這個問題的方法嗎?也許一種方法來檢查表單,看看它是否仍然存在?

+0

你會得到什麼例外? – 2010-06-18 07:42:38

回答

66

調用Close從窗體的構造函數是不可能的,因爲它會調用Dispose還沒有被創建的窗體上。要關閉施工後的形式,分配一個匿名事件處理程序,以顯示首次之前封閉表單中的Load event

public partial class MyForm : Form 
{ 
    public MyForm() 
    { 
     if (ShouldClose()) 
     { 
      Load += (s, e) => Close(); 
      return; 
     } 

     // ... 
    } 

    // ... 
} 
+8

+1,只需替換顯示爲無閃爍的負載,並且您有贏家 – Dialecticus 2012-06-04 10:32:18

+0

@Dialecticus:謝謝。完成! – Christian 2012-06-05 07:18:15

+0

這給了我這個錯誤:「執行CreateHandle()時無法調用Value Close()」 – GuidoG 2017-01-16 16:43:55

2

您的表單不會從構造函數中打開。你想達到什麼目的?

如果關閉此表單,那麼代碼路徑將完全退出,而沒有明顯的好處(即Application.Run將退出)。其他人發佈了關於隱藏表單的代碼,似乎更有可能。

4

你可以使MyFunc是靜態的嗎?然後做這樣的事情:

static void Main() 
{    
    ... 
    if (MyForm.MyFunc()) 
    { 
     Application.Run(new MyForm()); 
    } 
} 

這基本上會給你相同的控制是否將構建窗體?

9

當您在表單上調用Close()時,它會在內部處理表單並釋放所有受管資源。當你這樣做:

Application.Run(new MyForm()); 

你很可能會得到一個ObjectDisposedException。你需要做的是通過屬性設置窗體的可見性:

Application.Run(new MyForm() { Visible = false }); 

只要確保你刪除調用close()在構造函數中,甚至移動屬性分配也有。

20

你可以做的唯一的事情就是設置一個標誌在構造函數中關閉它,然後在Shown事件中關閉它。當然,如果你這樣做,移動代碼以確定它是否應該在那裏關閉是有道理的。

18

以下效果很好:

public partial class MyForm : Form 
{   
    public MyForm() 
    { 
     if (MyFunc()) 
     { 
      this.Shown += new EventHandler(MyForm_CloseOnStart); 
     } 
    } 

    private void MyForm_CloseOnStart(object sender, EventArgs e) 
    { 
     this.Close(); 
    } 
} 
4

我發現增加了處理的「加載」事件,因爲這更好對話從來沒有顯示出來。隨着「顯示的」事件中,你可能會短暫地看到對話框打開,然後關閉這可能會產生混淆:

public partial class MyForm : Form 
{   
    public MyForm() 
    { 
     if (MyFunc()) 
     { 
      this.Load += MyForm_CloseOnStart; 
     } 
    } 

    private void MyForm_CloseOnStart(object sender, EventArgs e) 
    { 
     this.Close(); 
    } 
} 
1

我認爲這不是明智的做法在構造函數中關閉窗體。如果你這樣做,表單的用戶不知道是否顯示對話框。

下面的代碼將是相當正常使用:

// in the parent form: 
public void ShowMyForm() 
{ 
    MyForm form = new MyForm(); 
    form.propertyA = ...; 
    from.propertyB = ...; 
    DialogResult dlgResult = form.ShowDialog(this); 
    ProcessDialogResult(dlgResult); 
} 

你必須添加特殊代碼,以決定是否ShowDialog的和是否處理對話的結果。

此外,你確定這些屬性不會影響表單是否被顯示嗎?還有未來的變化?

施工期間表格尚未顯示/打開。所以我害怕Close()沒有達到你的期望。

整潔的方法是在Form_Load中進行檢查。添加表單加載事件處理程序,並在那一刻進行檢查。使用屬性DialogResult來表明您決定不顯示錶單。

private void FormMain_Load (object sender, EventArgs e) 
{ 
    if (FormShouldNotLoad()) 
    { 
     this.DialogResult = System.Windows.Forms.DialogResult.Cancel; 
     Close(); 
    } 
} 

代碼的用戶可以勾選對話框的結果:

// in the parent form: 
public void ShowMyForm() 
{ 
    MyForm form = new MyForm(); 
    form.propertyA = ...; 
    from.propertyB = ...; 
    DialogResult dlgResult = form.ShowDialog(this); 
    switch (dlgResult) 
    { 
     case System.Windows.Forms.DialogResult.Cancel: 
      ... 
      break; 
     case System.Windows.Forms.DialogResult.OK: 
      ... 
      break; 
     // etc. 
    } 
} 

然而,這是行不通的,因爲關閉只能正確地加載完成後調用。因此,不應調用Close(),您應該先調用Close()函數,以便在加載完成後調用Close函數:

加載完成後調用Close()的代碼將如下所示:

private void FormMain_Load (object sender, EventArgs e) 
{ 
    if (MyFunc()) 
    { 
     CancelLoading(); 
    } 
} 

private delegate void InvokeDelegate(); 

private void CancelLoading() 
{ // will cancel loading this form 
    this.DialogResult = System.Windows.Forms.DialogResult.Cancel; 
    this.BeginInvoke(new InvokeDelegate(CloseThisForm)); 
} 

private void CloseThisForm() 
{ 
    this.Close(); 
} 

的好處是,在OnFormClosing和OnFormClosed你知道的形式完全相同的地位:它是完全加載,所以你知道在關閉時該怎麼做。

+0

這應該是公認的答案,目前接受的答案編譯但給出了運行時錯誤。 – GuidoG 2017-01-16 16:58:11

1

如果你希望你的窗口永遠不會看到
(無閃爍的窗戶,打開瞬間,然後消失)

public new void Show() 
{ 
    if (MyFunc()) 
     base.Show(); 
    else 
     ; // dispose or whatever 
} 

雖然Show(...)有2個過載和ShowDialog(...)有2個了。
對於通過Application.Run()打開的主窗體不起作用。但是誰會這樣做呢?除了還有一種方法可以在不使用Application.Run()的情況下打開主窗體。