Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
WPF-практика 5 События и команды.doc
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
2.21 Mб
Скачать

Обработка системной кнопки

Пока в приложение закрался один существенный недостаток. Когда документ содержит несохраненные изменения и пользователь завершает работу приложения по нашей команде Exit, то все в порядке - приложение извещает о необходимости их сохранить. Но когда окно закрывается по системной кнопке, то извещение отсутствует. Исправим это, для чего воспользуемся событием Closing. В отличии от Closing событие Closed возбудается, когда отменить закрытие окна уже невозможно, а можно только что-то доделать.

  • Присоедините к открывающему дескриптору окна Window1 в файле Window1.xaml обработчик события Closing, которое будет возбуждаться при попытке закрытия окна любым способом

<Window x:Class="Notepad1.Window1"

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

Title="Window1: Управление состоянием источников команд"

Width="500" Height="375"

MinWidth="500" MinHeight="375"

WindowStartupLocation="CenterScreen"

ResizeMode="CanResizeWithGrip"

Loaded="Window_Loaded"

Icon="Notepad.ico"

Closing="Window_Closing"

>

  • Заполните обработчик события Closing следующим кодом

private void Window_Closing(object sender,

System.ComponentModel.CancelEventArgs e)

{

if (!CheckModifiedAndSaveIt())

{

e.Cancel = true;

return; // Пользователь передумал выходить

}

}

  • Запустите приложение - теперь сообщение о несохраненных изменениях выводится и при попытке закрытия окна системной кнопкой

Обратите внимание, что при закрытии окна через наше меню задачей Exit на кнопку отказа от сохранения надо щелкать 2 раза. Это связано с тем, что в обработчике события Closing проверка повторяется. Значит при выходе через меню проверку в обработчике события Closing нужно блокировать с помощью флага.

  • Добавьте в класс Window1 поле-флаг _IsExitItem и модифицируйте соответствующим образом обработчики

bool _IsExitItem = false;

private void ExitOnExecute(object sender, RoutedEventArgs e)

{

if (!CheckModifiedAndSaveIt())

return; // Пользователь передумал выходить

_IsExitItem = true;

Close();

}

private void Window_Closing(object sender,

System.ComponentModel.CancelEventArgs e)

{

/*

// Эта проверка была бы надежнее

if(_IsExitItem)

return;

*/

// !_IsExitItem должен в условии стоять первым

if (!_IsExitItem && !CheckModifiedAndSaveIt())

{

e.Cancel = true;

_IsExitItem = false;

return; // Пользователь передумал выходить

}

}

В последнем обработчике есть один поучительный нюанс: если в условии проверку значения флага поставить последним, то код будет реагировать на наши нововведения. Это происходит потому, что логическое умножение проверяется компилятором слева направо до первого ложного значения. В нашем случае если флаг _IsExitItem==true, то функция CheckModifiedAndSaveIt() выполняться уже не будет. Такой код менее надежен, поскольку зависит от компилятора, да и мы (или сопровождающий программист) можем случайно переставить члены выражения местами. Поэтому лучше заменить этот код на более ясный, как показано в коментариях.

  • Запустите приложение и испытайте работу закрытия окна при несохраняемых изменениях