Предлагать пользователю сохранить при закрытии приложения

Я пишу то, что сводится к редактору документов. Когда приложение закрывается, мне нужно предложить пользователю сохранить изменения. Это достаточно просто. Мой вопрос в том, когда уместно нет запрашивать пользователя, а вместо этого просто отбрасывать несохраненные данные и закрывать.

В событии FormClosing перечисление CloseReason включает:

  • Никто
  • WindowsShutDown
  • MdiFormClosing
  • UserClosing
  • TaskManagerClosing
  • FormOwnerClosing
  • ApplicationExitCall

Я полагаю, что 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;
        }
    }
}
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
5
0
1 794
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

Ответ принят как подходящий

Я думаю, что TaskManagerClosing должен быть единственной причиной, которая не подскажет, если таковая имеется. Лично я хотел бы получить подсказку в случае WindowsShutDown. Если я где-то закрываю Windows с несохраненным документом, значит, я забыл об этом.

Я лично предпочитаю просто закрывать программу, когда пользователь выбирает закрытие, если есть какие-либо несохраненные документы в момент закрытия, я предпочитаю хранить резервные копии этих файлов и сообщать пользователю, что есть несохраненные документы, когда они в следующий раз откроют приложение.

Я делаю это по нескольким причинам, во-первых, мне нравится, когда мои приложения закрываются, когда я говорю им о закрытии, и во-вторых, сохраняя временную копию файла, который я обновляю со всеми изменениями, когда пользователь работает над ним. Я защищаю от неожиданных сбоев и закрытий моих приложений.

Таким образом, с помощью этой техники вам не нужно беспокоиться о закрытии приложения.

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

Jon B 20.01.2009 23:24

Идея мне нравится, но Джон Б. прав ... это сильно нарушает принцип наименьшего удивления.

rmeador 20.01.2009 23:31

Я думаю, вы хотите сказать, что это противоречит тому, как работает Microsoft Office. Vim работает таким образом, и я должен сказать, что лично я большой поклонник этой функции, она спасла меня не раз. Итак, я начал внедрять его во все свои приложения, которые я создаю.

CalvinR 20.01.2009 23:32

Я не знаю, я думаю, что ожидание выхода приложения, когда пользователь закрывает приложение, является наименее неожиданным результатом в этой ситуации.

CalvinR 20.01.2009 23:34

CalvinR ​​- Я не отвергаю идею автосохранения, я просто думаю, что пользователи ожидают появления сообщения «Сохранить изменения?» запрашивать при закрытии (при наличии ожидающих изменений). В моем случае я думаю, что мои пользователи более знакомы с Office, чем с Vim.

Jon B 21.01.2009 00:04

Я не знаю, как вы имеете в виду, что у Vim такое поведение ... если вы это сделаете: q, он предложит вам сохранить (если вы не сделаете: q!). Если это gvim, и вы нажмете X, отобразится графическая подсказка. Если вы используете команду kill для отправки ему сигнала, он закроется беззвучно, что аналогично TaskManagerClosing.

rmeador 21.01.2009 00:30

Я бы определенно также показал диалоговое окно «Вы хотите сохранить» в 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 в том, что важнее избегать запроса на сохранение, если данные не изменились с момента последнего сохранения. Обычно я использую простой флаг «изменено», который устанавливается при любом действии редактирования и сбрасывается при сохранении и загрузке.

Другие вопросы по теме