Як я можу програмно вийти із програми 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 (WPF) у таких ситуаціях:

  • Коли для параметра ShutdownMode встановлено значення OnLastWindowClose.
  • Коли для параметра ShutdownMode встановлено значення OnMainWindowClose.
  • Коли користувач закінчує сеанс, і подія SessionEnding або обробляється без обробки, або обробляється без скасування.

Зверніть також увагу, що Application.Current.Shutdown();виклик може бути лише з потоку, який створив Applicationоб'єкт, тобто зазвичай основного потоку.


8
Як я зазначив, це не дивно. У WPF Application є статичний клас. Application.Current - це посилання на ваш запущений додаток.
ТимофійП

4
На мою думку, це трохи дивно в тому сенсі, що це не очевидно на перший погляд, і це досить відхиляється від минулих моделей, щоб скинути людей. Це має ідеальний сенс, що це працює звичайно.
Брайан Маккей

20
Якщо ви зателефонуєте, Application.Current.Shutdown();ваш фонд не повернеться негайно Для цього вам потрібно зателефонувати return;.
Ервін Майер

2
Я використав це, коли з одного вікна спливе інше вікно, і в цьому випадку вікно_ закритого події я додав цей код. всі вікна зникають, але програма все ще працює там, де після створення спливаючого вікна.
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

Як сказав wuminqi ,Application.Current.Shutdown(); це незворотно, і я вважаю, що його зазвичай використовують, щоб примусити програму закриватись у такі періоди, як, наприклад, коли користувач виходить із системи чи закриває Windows.

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

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


2
+1 Я вирішив перейти з цим, тим більше, що мені потрібно зберегти відкриті файли, перш ніж вийти з програми.
AgentKnopf

2
Тут важливо відзначити той факт, що Аллен зазначив дуже важливий факт: всі інші вікна, що належать до власності, будуть закриті. Ви повинні переконатися, що заявляєте про право власності. Якщо у вас запущене вікно, а потім ви відкриєте інше вікно, але ще не показуєте його, після закриття активного вікна приховане вікно змусить програму продовжувати працювати. У вас буде потенційна витік пам'яті, якщо ви не закриєте це вікно іншими засобами (диспетчером завдань тощо). Я це перевірив.
БК

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 це буде працювати, але інший спосіб, як this.close, не працює в багатопотокових програмах, коли працює інший потік.
Алі Юсефі

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.
mehdi


6

На моє розуміння, Application.Current.Shutdown()має і свій недолік.

Якщо ви хочете показати вікно підтвердження, щоб дозволити користувачам підтвердити, що вийшли чи ні, Application.Current.Shutdown()це незворотно.


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

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

Veer: У моєму випадку з'являється вікно підтвердження, але навіть коли ви підтверджуєте, що у підтвердженні ви виберете "Скасувати", головне APP закривається.
wuminqi

7
СТС: Це краще розробляти в кожному конкретному випадку. У нашому додатку, якщо виконуються завдання, виїзд примусово спричинить збитки, тому краще повідомити їх у діалоговому вікні підтвердження
wuminqi

3

Підсумовуючи, є кілька способів зробити це.

1) Вбивство процесу, яке пропускає завершення, обробку помилок тощо:

Process.GetCurrentProcess().Kill();

2) Вимкнення поточного додатка, який, мабуть, є правильним способом, оскільки він викликає події виходу:

Application.Current.Shutdown();

або

this.Shutdown();

(при натисканні на екземпляр App-класу)

3) Закриття поточного додатка (усі форми потрібно закрити / заповнити раніше):

this.Close(); 

(при натисканні на екземпляр App-класу)

4) Вихід із середовища, який припиняє додаток:

Environment.Exit(0);

Крім того , Ви можете прочитати про вихід statusses тут


2

Гарбуз мікросолодкий

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
Anders

0

Якщо ви хочете вийти з іншого потоку, який не створив об’єкт програми, використовуйте:

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

-2

Application.Current.ShutdownMode = ShutdownMode.OnExplicitShutdown;


2
Ласкаво просимо до SO, Alpha-LIon! Тут не рекомендується відповідати лише на код, оскільки вони не дають уявлення про те, як проблема була вирішена. Будь ласка, оновіть своє рішення з поясненням того, як ваш код вирішує проблему ОП :)
Joel

-3

З коду xaml можна зателефонувати заздалегідь визначеним SystemCommand:

Command="SystemCommands.MinimizeWindowCommand"

Я думаю, що це має бути кращим способом ...


Мінімізуйте! = Вихідний додаток. У цьому списку я не бачу опції програми для виходу. Здається, більше управління вікнами та закриття вікна не обов'язково означає закриття програми. msdn.microsoft.com/en-us/library / ...
Kenny
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.