在调用Application.Run()之前关闭(退出)和应用程序?

时间:2012-01-16 11:47:43

标签: winforms visual-studio c#-4.0

我无法理解如何关闭C#.NET winforms应用程序。我想做的是:

显示表单以允许用户根据需要设置环境 如果用户按下“确定”按钮,请执行一些逻辑来设置应用程序环境(实例化对象等) 如果用户按“取消”或关闭窗口,请关闭应用程序。

问题是,我在main(1st)表单之前调用环境设置表单。这是最近的需求变化,我并不想重新编写我从一开始就拥有的代码。

我的代码(应该比我的小序言更有意义)是:

    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());

所以Main表单(和app)无论如何运行。有没有更好的方法来做我想做的事情?

编辑:为清楚起见,我的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());
        }
     }
   }

3 个答案:

答案 0 :(得分:2)

将逻辑从构造函数移动到main方法。 由于它与应用程序的启动有关而不是形式,因此将它作为启动逻辑的一部分是有意义的。

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);             
    }  
}

拥有这种逻辑,特别是因为它是模态并停止执行,在构造函数中不是一个好主意。您希望构造函数是对象的简单初始化并且是可重复的。例如。如果你在某些时候需要再次构建主窗体,那么我不想在那个时间点弹出窗口

答案 1 :(得分:2)

表单的构造函数及其OnLoad或Load事件都不是放置此代码的好地方。在Application.Run()调用之前,构造函数由于Main()方法中的new MainForm()语句而运行。 Load事件被触发,因为Application类调用Show()方法,在Application.Run()进入消息循环之前隐藏在框架代码中。在消息循环开始运行之前,Application.Exit()无法执行任何操作。

解决方法是将此代码移动到Program.cs中的Main()方法。使它看起来类似于:

    [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);
    }

答案 2 :(得分:-1)

将代码移到“InitializeComponent();”下面到MainForm_Load事件

在Mainform_Load事件而不是执行Application.Exit()只关闭()表单,这也应该关闭应用程序。