Закрытие (Выход) и Приложение до вызова Application.Run ()? - PullRequest
2 голосов
/ 16 января 2012

У меня проблемы с пониманием того, как закрыть приложение winforms C # .NET.Я пытаюсь сделать следующее:

Показать форму, позволяющую пользователю настроить среду так, как он хочет. Если пользователь нажимает кнопку «ОК», выполните некоторую логику для настройки среды приложения.(создание объектов и т. д.) Если пользователь нажимает «Отмена» или закрывает окно, закройте приложение.

Проблема в том, что я вызываю форму настройки среды перед основной (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());
        }
     }
   }

Ответы [ 3 ]

2 голосов
/ 16 января 2012

Переместите логику из конструктора в основной метод. Поскольку это связано с запуском приложения, а не с формой, имеет смысл включить его в логику запуска.

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

Наличие такой логики, особенно потому что она модальная и останавливает выполнение, в конструкторе не очень хорошая идея. Вы хотите, чтобы ваши конструкторы были простой инициализацией объекта и были бы повторяемыми. Например. если в какой-то момент вам понадобится снова создать основную форму, вы не захотите всплывающее окно в этот момент, я думаю

2 голосов
/ 16 января 2012

Ни конструктор формы, ни событие OnLoad или Load не являются подходящими местами для размещения этого кода. Конструктор выполняется из-за оператора new MainForm() в методе Main () перед вызовом Application.Run (). Событие Load вызывается тем, что класс Application вызывает метод Show (), скрытый внутри кода платформы непосредственно перед тем, как Application.Run () входит в цикл обработки сообщений. Application.Exit () не может ничего делать, пока не начнет работать этот цикл сообщений.

Обходной путь - переместить этот код в метод Main () в 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);
    }
0 голосов
/ 16 января 2012

Переместите свой код ниже «InitializeComponent ();» событие MainForm_Load

на событии Mainform_Load вместо Application.Exit () просто закройте () форму, это также должно закрыть приложение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...