Как программно выйти из приложения 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()защищает меня от непреднамеренных недостатков дизайна.

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

BK
источник
16

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

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

Application.Current.Shutdown();
TimothyP
источник
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);
}
Ravi
источник
это не вопрос ответа, он хочет знать, как выйти из приложения wpf.
Мехди
6

Пытаться

App.Current.Shutdown();

Для меня

Application.Current.Shutdown(); 

не работал

Ивона Кубович
источник
6

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

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

wuminqi
источник
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);

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

Burgund
источник
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();
SoumyaMahunt
источник
-2

Application.Current.ShutdownMode = ShutdownMode.OnExplicitShutdown;

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

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

Command="SystemCommands.MinimizeWindowCommand"

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

Маркус Соммершнее
источник
Свернуть! = Выйти из приложения. Я не вижу опции выхода из приложения в этом списке. Кажется, больше управления окнами и закрытие окна не обязательно означает закрытие приложения. msdn.microsoft.com/en-us/library/...
Kenny