Я пишу то, что сводится к редактору документов. Когда приложение закрывается, мне нужно предложить пользователю сохранить изменения. Это достаточно просто. Мой вопрос в том, когда уместно нет запрашивать пользователя, а вместо этого просто отбрасывать несохраненные данные и закрывать.
В событии FormClosing перечисление CloseReason включает:
Я полагаю, что WindowsShutDown и TaskManagerClosing не должны вызывать "сохранить изменения?" приглашение появиться, чтобы предотвратить зависание приложения с отображением этого запроса.
Это стандартная практика, или мне следует заняться здесь чем-то другим?
Для наглядности вот код:
protected override void OnFormClosing(FormClosingEventArgs e)
{
base.OnFormClosing(e);
if (!(e.CloseReason == CloseReason.WindowsShutDown || e.CloseReason == CloseReason.TaskManagerClosing)
&& this.ChangesPending())
{
switch (MessageBox.Show(this, "Save changes?", "Save Changes", MessageBoxButtons.YesNoCancel))
{
case DialogResult.Yes:
this.Save();
break;
case DialogResult.No:
// Do nothing
break;
case DialogResult.Cancel:
e.Cancel = true;
break;
}
}
}





Я думаю, что TaskManagerClosing должен быть единственной причиной, которая не подскажет, если таковая имеется. Лично я хотел бы получить подсказку в случае WindowsShutDown. Если я где-то закрываю Windows с несохраненным документом, значит, я забыл об этом.
Я лично предпочитаю просто закрывать программу, когда пользователь выбирает закрытие, если есть какие-либо несохраненные документы в момент закрытия, я предпочитаю хранить резервные копии этих файлов и сообщать пользователю, что есть несохраненные документы, когда они в следующий раз откроют приложение.
Я делаю это по нескольким причинам, во-первых, мне нравится, когда мои приложения закрываются, когда я говорю им о закрытии, и во-вторых, сохраняя временную копию файла, который я обновляю со всеми изменениями, когда пользователь работает над ним. Я защищаю от неожиданных сбоев и закрытий моих приложений.
Таким образом, с помощью этой техники вам не нужно беспокоиться о закрытии приложения.
Идея мне нравится, но Джон Б. прав ... это сильно нарушает принцип наименьшего удивления.
Я думаю, вы хотите сказать, что это противоречит тому, как работает Microsoft Office. Vim работает таким образом, и я должен сказать, что лично я большой поклонник этой функции, она спасла меня не раз. Итак, я начал внедрять его во все свои приложения, которые я создаю.
Я не знаю, я думаю, что ожидание выхода приложения, когда пользователь закрывает приложение, является наименее неожиданным результатом в этой ситуации.
CalvinR - Я не отвергаю идею автосохранения, я просто думаю, что пользователи ожидают появления сообщения «Сохранить изменения?» запрашивать при закрытии (при наличии ожидающих изменений). В моем случае я думаю, что мои пользователи более знакомы с Office, чем с Vim.
Я не знаю, как вы имеете в виду, что у Vim такое поведение ... если вы это сделаете: q, он предложит вам сохранить (если вы не сделаете: q!). Если это gvim, и вы нажмете X, отобразится графическая подсказка. Если вы используете команду kill для отправки ему сигнала, он закроется беззвучно, что аналогично TaskManagerClosing.
Я бы определенно также показал диалоговое окно «Вы хотите сохранить» в WindowsShutDown (приложение могло, например, какое-то время работать в фоновом режиме, и пользователь забыл об этом, или он мог щелкнуть «Перезагрузить» после пакета обновления был установлен недолго думая и тд).
Что касается TaskManagerClosing, я бы в этом случае не показывал диалог.
На самом деле CloseReason - спорный вопрос, не так ли? Тот факт, что ваша форма уходит, - это то, что вы пытаетесь уловить.
Теперь вам нужно знать, обработало ли ваше приложение уже событие «save». Если это так, форма может исчезнуть. Вы сохранили свой документ. Но если нет, вы можете попросить пользователя об этом.
Если вы можете быстро проверить данные (т. Е. Выполнить сравнение строк или хешей в документе по сравнению с данными в файле), тогда вы узнаете, сохранил ли пользователь данные формы.
В противном случае, если имеется много полей и проверка каждого из них требует ресурсов, установите флаг isDirty в вашу форму. Пусть метод Save () устанавливает для isDirty значение false, а любое другое изменение поля устанавливает для него значение true.
Затем в формеClosing все, что вам нужно, это:
protected override void OnFormClosing(FormClosingEventArgs e)
{
if (isDirty)
{
DialogResult R = MessageBox.Show(this, "Save changes?", "Save Changes",
MessageBoxButtons.YesNoCancel);
if (R == DialogResult.Yes)
{
this.Save();
} else if (R == DialogResult.Cancel)
{
e.Cancel = true;
}
}
}
Думаю, даже TaskManagerClosing может использовать подсказку для сохранения. Если ваше приложение работает нормально, его закрытие через диспетчер задач не должно отличаться от любого другого способа закрытия. Если он завис, не имеет значения, что делает ваш обработчик onClose - он никогда не доберется до него.
Я согласен с @Jerry в том, что важнее избегать запроса на сохранение, если данные не изменились с момента последнего сохранения. Обычно я использую простой флаг «изменено», который устанавливается при любом действии редактирования и сбрасывается при сохранении и загрузке.
Это очень сильно противоречит тому, как работает большинство приложений - я думаю, пользователь ожидает, что он получит запрос, когда приложение закроется в обычном режиме.