Как программно выйти из приложения WPF?


478

В течение нескольких лет я использовал C # (Windows Forms), я никогда не использовал WPF. Но теперь я люблю WPF, но я не знаю, как мне выйти из приложения, когда пользователь нажимает на пункт «Выход» из меню «Файл».

Я пытался:

this.Dispose();
this.Exit();
Application.ShutDown();
Application.Exit();
Application.Dispose();

Среди многих других. Ничего не работает

Ответы:


781

Для выхода из приложения вы можете позвонить

System.Windows.Application.Current.Shutdown();

Как описано в документации к Application.Shutdownметоду, вы также можете изменить поведение завершения работы вашего приложения, указав ShutdownMode :

Windows Presentation Foundation (WPF) неявно вызывается в следующих ситуациях:

  • Когда ShutdownMode имеет значение OnLastWindowClose.
  • Когда ShutdownMode имеет значение OnMainWindowClose.
  • Когда пользователь завершает сеанс и событие SessionEnding либо не обрабатывается, либо обрабатывается без отмены.

Также обратите внимание, что он Application.Current.Shutdown();может быть вызван только из потока, который создал Applicationобъект, то есть обычно из основного потока.


8
Как я уже говорил, это не странно. В WPF Application это статический класс. Application.Current - это ссылка на ваше текущее приложение.
— TimothyP

4
На мой взгляд, это немного странно в том смысле, что это неочевидно на первый взгляд, и оно настолько отклоняется от прошлых моделей, чтобы отбросить людей. Совершенно очевидно, что это работает, конечно.
— Брайан Маккей

20
Если вы позвоните, Application.Current.Shutdown();ваша функция не вернется сразу. Вам также нужно позвонить return;для этого.
— Эрвин Майер

2
Я использовал это, когда из одного окна появляется другое окно, и в событии window_closed этого окна я добавил этот код. все окна исчезают, но после запуска всплывающего окна программа все еще работает.
— diyoda_

7
@TimothyP Нет, Applicationэто НЕ статический класс. Наличие Application.Currentстатического члена не означает, что он статический. Вместо этого это нормальный класс, который можно получить.
— Земля Двигатель

156

Если вам действительно нужно это закрыть, вы также можете использовать Environment.Exit () , но это совсем не изящно (больше похоже на завершение процесса).

Используйте это следующим образом:

Environment.Exit(0)

4
Environment.Exit()нужен хотя бы один параметр, код выхода. Используйте, Environment.Exit(0)если вас не интересует код выхода.
— gbmhunter

24
Этот метод фактически закрыл все. Мое приложение оставляло что-то работающее (форма закрывалась, но процесс все еще работал) сApplication.Current.Shutdown();
— gbmhunter

4
Environment.Exit - определенно правильный способ обеспечить завершение работы приложения. С Application.Current.Shutdown вы можете легко запустить приложение на неопределенное время, если у вас есть код, который возвращается в диспетчер.
— Маркус Андрэн

Равный Application.exit (0);
— Сайка

С Application.Current.Shutdown();моим Closingсобытием было вызвано, когда я просто хотел немедленно закрыть приложение. Так Environment.Exit(0);был лучший выбор.
— FredM

64

Как сказал Вуминци ,Application.Current.Shutdown(); он необратим, и я считаю, что он обычно используется для принудительного закрытия приложения в такие моменты, как когда пользователь выходит из системы или закрывает Windows.

Вместо этого позвоните this.close()в главное окно. Это то же самое, что нажать Alt+ F4или закрыть кнопку [x] в окне. Это приведет к закрытию всех других принадлежащих ему окон и вызовет их, Application.Current.Shutdown();пока действие закрытия не было отменено. Пожалуйста, смотрите документацию MSDN по закрытию окна .

Кроме того, поскольку его this.close()можно отменить, вы можете поместить его в диалог подтверждения сохранения изменений в обработчике закрывающих событий. Просто создайте обработчик события <Window Closing="...">и измените его e.Cancelсоответствующим образом. ( Подробнее о том, как это сделать, см. Документацию MSDN .)


2
+1 Я решил пойти с этим, тем более, что мне нужно сохранить открытые файлы перед тем, как выйти из приложения.
— AgentKnopf

2
Здесь важно отметить, что Аллен указал на очень важный факт: все остальные окна будут закрыты. Вы должны убедиться, что вы заявляете право собственности. Если у вас есть окно, которое работает, а затем вы открываете другое окно, но еще не открываете его, после закрытия активного окна скрытое окно заставит приложение продолжать работу. У вас будет потенциальная утечка памяти, если вы не закроете это окно другими средствами (диспетчер задач и т. Д.). Я проверял это.
— BK

35

При необходимости используйте любое из следующего:

1.

 App.Current.Shutdown();
OR
 Application.Current.Shutdown();

2.

 App.Current.MainWindow.Close();
OR
 Application.Current.MainWindow.Close();

Выше все методы будут вызывать closing eventиз Windowкласса и выполнение может остановиться на каком - то момент (причина , как правило , приложение ставить диалоги , как «вы уверены?» Или « вы бы хотели сохранить данные перед закрытием? », Перед тем, как окно полностью закрыто)

3. Но если вы хотите прекратить приложение без предупреждения немедленно. Используйте ниже

   Environment.Exit(0);


18

Вот как я делаю мои:

// Any control that causes the Window.Closing even to trigger.
private void MenuItemExit_Click(object sender, RoutedEventArgs e)
{
    this.Close();
}

// Method to handle the Window.Closing event.
private void Window_Closing(object sender, CancelEventArgs e)
{
    var response = MessageBox.Show("Do you really want to exit?", "Exiting...",
                                   MessageBoxButton.YesNo, MessageBoxImage.Exclamation);
    if (response == MessageBoxResult.No)
    {
        e.Cancel = true;
    }
    else
    {
        Application.Current.Shutdown();
    }
}

Я звоню только Application.Current.ShutDown()из главного окна приложения, все остальные окна используют this.Close(). В моем главном окне Window_Closing(...)обрабатывает верхнюю правую xкнопку. Если какой-либо из методов вызывает окно ближе, Window_Closing(...)захватывает событие для выключения, если пользователь подтверждает.

Причина, по которой я действительно использую Application.Current.Shutdown()свое главное окно, заключается в том, что я заметил, что если была допущена ошибка проектирования, и я не объявил родителя одного из моих окон в приложении, если это окно открывается без предварительного отображения до последнего закрытия активного окна у меня остается скрытое окно, работающее в фоновом режиме. Приложение не будет закрыто. Единственный способ предотвратить полную утечку памяти - это зайти в диспетчер задач, чтобы закрыть приложение. Application.Current.Shutdown()защищает меня от непреднамеренных недостатков дизайна.

Это из моего личного опыта. В конце концов, используйте то, что лучше для вашего сценария. Это просто еще одна часть информации.


16

Там не должно быть Application.ShutDown();или .Exit()сообщение.

Applicationэто статический класс. Это не относится к текущему приложению. Вам нужно перейти к текущему приложению, а затем закрыть его следующим образом:

Application.Current.Shutdown();

8

Еще один способ сделать это:

System.Diagnostics.Process.GetCurrentProcess().Kill();

Это заставит убить ваше приложение. Это всегда работает, даже в многопоточном приложении.

Примечание: просто будьте осторожны, чтобы не потерять несохраненные данные в другом потоке.


Это кажется непостижимым: «в процессе всегда работает» . Ты можешь починить это? Или хотя бы объясните здесь, в комментариях, что вы имеете в виду?
— Питер Мортенсен

Это также отчасти непонятно: просто позаботьтесь о приложении, в котором данные сохранены в файлах из другого потока. Ты можешь починить это? Или хотя бы объясните здесь, в комментариях, что вы имеете в виду?
— Питер Мортенсен

Вы используете Google Translate?
— Питер Мортенсен

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

6
private void _MenuExit_Click(object sender, RoutedEventArgs e)
{
   System.Windows.Application.Current.MainWindow.Close();
}

//Override the onClose method in the Application Main window

protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
{
    MessageBoxResult result =   MessageBox.Show("Do you really want to close", "",
                                          MessageBoxButton.OKCancel);
    if (result == MessageBoxResult.Cancel)
    {
       e.Cancel = true;
    }
    base.OnClosing(e);
}

это не вопрос ответа, он хочет знать, как выйти из приложения wpf.
— Мехди


6

По моему пониманию, Application.Current.Shutdown()тоже имеет свой недостаток.

Если вы хотите показать окно подтверждения, чтобы позволить пользователям подтвердить при выходе или нет, Application.Current.Shutdown()необратимо.


7
Я не понимаю этого. Мы можем получить подтверждение пользователя перед тем, как позвонить Application.Current.Shutdown().
— Амсаканна

2
Я не понимаю, почему вы должны подтвердить. Слишком много подтверждений - очень плохая вещь. Тот факт, что кто-то попытался щелкнуть, чтобы открыть меню «Файл», переместиться до самого конца меню «Файл» и нажать «Выход», в значительной степени подтверждает, что он больше не хочет использовать приложение.

Veer: В моем случае окно подтверждения действительно появляется, но даже когда вы выбираете «отмена» в подтверждении, основное приложение закрывается.
— wuminqi

7
СТС: Это лучше разрабатывать в каждом конкретном случае. Наше приложение, если есть запущенные задания, принудительный выход вызовет повреждения, поэтому лучше сообщить им об этом в диалоговом окне подтверждения
— wuminqi

3

Подводя итог, есть несколько способов сделать это.

1) Уничтожение процесса, который пропускает финализацию, обработку ошибок и т.д .:

Process.GetCurrentProcess().Kill();

2) Завершение работы текущего приложения, что, вероятно, является правильным способом, потому что оно вызывает события выхода:

Application.Current.Shutdown();

или

this.Shutdown();

(при подключении в экземпляре класса App)

3) Закрытие текущего приложения (все формы должны быть закрыты / закончены ранее):

this.Close(); 

(при подключении в экземпляре класса App)

4) Выход из среды, которая завершает приложение:

Environment.Exit(0);

Также вы можете прочитать о статусах выхода здесь


2

Caliburn микро ароматизированный

public class CloseAppResult : CancelResult
{
    public override void Execute(CoroutineExecutionContext context)
    {
        Application.Current.Shutdown();
        base.Execute(context);
    }
}

public class CancelResult : Result
{
    public override void Execute(CoroutineExecutionContext context)
    {
        OnCompleted(this, new ResultCompletionEventArgs { WasCancelled = true });
    }
}

Что означает «Caliburn micro flavored» ?
— Питер Мортенсен

Как вы этого добьетесь, используя Caliburn Micro
— Anders

0

Если вы хотите выйти из другого потока, который не создал объект приложения, используйте:

System.Windows.Application.Current.Dispatcher.InvokeShutdown();

-2

Application.Current.ShutdownMode = ShutdownMode.OnExplicitShutdown;


2
Добро пожаловать в альфа-лион! Здесь не рекомендуется отвечать только на код, так как они не дают представления о том, как проблема была решена. Пожалуйста, обновите ваше решение с объяснением того, как ваш код решает проблему ОП :)
— Джоэл

-3

Из кода xaml вы можете вызвать предопределенную SystemCommand:

Command="SystemCommands.MinimizeWindowCommand"

Я думаю, что это должно быть предпочтительным способом ...


Свернуть! = Выйти из приложения. Я не вижу опции выхода из приложения в этом списке. Кажется, больше управления окнами и закрытие окна не обязательно означает закрытие приложения. msdn.microsoft.com/en-us/library/...
— Kenny
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.