2012-01-16 102 views
2

我無法理解如何關閉C#.NET winforms應用程序。我想要做的是:在調用Application.Run()之前關閉(退出)和應用程序?

顯示一個表單,允許用戶設置他們想要的環境 如果用戶按下「確定」按鈕,執行一些設置應用程序環境的邏輯(實例化對象等) 如果用戶按下「取消」或關閉窗口,關閉應用程序。

的問題是,我打電話的環境設置形式爲主(1)形式之前。這是最近的需求變化,我不喜歡重新編寫我從一開始就有的代碼。

我有(這應該比我小序言更有意義)的代碼是:

public MainForm() 
    { 
     InitializeComponent(); 
     //Get the user to set-up the environment (load specific config files, etc) 

     environmentSetupForm newEnvrionmenSetupForm = new environmentSetupForm(); 
     if (newEnvrionmenSetupForm .ShowDialog() == DialogResult.OK) 
     { 
      newEnvrionmenSetupForm .Close(); 
      //some logic based on what the user selected on the set-up form 
     } 
     else 
     { 
      //Since the user didn't set-up the environment correctly (there 
      //was a message box, informing them and giving them another 
      //shot at it), exit out of the application. 
      Application.Exit(); 
     } 
    } 

我唯一的問題是,經過Application.Exit(),堆棧跳回的Program.cs和執行

 Application.Run(new MainForm()); 

因此主窗體(和應用程序)無論如何運行。有沒有更好的方式來做我想做的事情?

編輯:爲清楚起見,我的Program.cs代碼讀取:

using System; 
    using System.Collections.Generic; 
    using System.Linq; 
    using System.Windows.Forms; 

    namespace myNamespace 
    { 
     static class Program 
     { 
     /// <summary> 
     /// The main entry point for the application. 
     /// </summary> 
     [STAThread] 
     static void Main() 
     { 
      Application.EnableVisualStyles(); 
      Application.SetCompatibleTextRenderingDefault(false); 
      Application.Run(new MainForm()); 
     } 
    } 
    } 

回答

2

窗體的構造函數或它的OnLoad或Load事件都不是放置此代碼的好地方。由於Main()方法中的new MainForm()語句在構造函數的Application.Run()調用之前運行。由於Application類在Application.Run()進入消息循環之前調用Show()方法,因此隱藏在框架代碼中,因此Load事件被觸發。在消息循環開始運行之前,Application.Exit()不能執行任何操作。

解決方法是這個代碼移動到主Program.cs中()方法。使它看起來類似於這樣:

[STAThread] 
    static void Main() { 
     Application.EnableVisualStyles(); 
     Application.SetCompatibleTextRenderingDefault(false); 
     MainForm main;    
     using (var dlg = new environmentSetupForm()) { 
      if (dlg.ShowDialog() != DialogResult.OK) return; 
      // Use dlg values 
      //... 
      main = new MainForm(); 
      // Make main form show up at the same location 
      main.StartPosition = FormStartPosition.Manual; 
      main.Location = dlg.Location; 
     } 
     Application.Run(main); 
    } 
-1

移動以下代碼 「的InitializeComponent();」到MainForm_Load事件

在Mainform_Load事件,而不是做一個Application.Exit()剛剛關閉()的形式,這應該關閉應用程序也是如此。

+0

想想你的解釋,你的代碼不匹配,這就是問題所在,你可以檢查,如果你提供正確的示例代碼或編輯納入您的Program.cs中的代碼? – 2012-01-16 12:50:05

+0

@JesusSalas:我已經編輯包含我的Program.cs – 2012-01-16 13:07:15

+2

@JamieTaylor耶穌是對的;你所描述的與你的代碼不一樣。你對'Application.Exit()'調用後發生的事情不正確。你已經在Application.Run()中運行*了,所以不行 - 它不再輸入。你的邏輯必須在某個地方倒退。 – 2012-01-16 13:10:11

2

將邏輯從構造函數移至主方法。 由於它與應用程序的啓動有關,而不是形式,所以將它作爲啓動邏輯的一部分是有意義的。

static void Main()    { 
    Application.EnableVisualStyles();    
    Application.SetCompatibleTextRenderingDefault(false); 
    var newEnvrionmenSetupForm = new environmentSetupForm(); 
    if (newEnvrionmenSetupForm .ShowDialog() == DialogResult.OK)   { 
     newEnvrionmenSetupForm .Close(); 
     //some logic based on what the user selected on the set-up form 
     var mainform = new MainForm(); 
     Application.Run(mainform);    
    } 
} 

有那種邏輯的,尤其是因爲它的模式,並停止執行,在構造函數是不是一個好主意。你希望你的構造函數能夠簡單地初始化對象並且是可重複的。例如。如果你在某一時刻需要再次構造主窗體,那麼你不會想要那個時間點的彈出窗口,我猜

相關問題