Элегантный способ уменьшить дублирование кода между запросом пользователя сохранить при закрытии программы?

При выходе из программы, если программист обрабатывает FormClosing В случае, если есть несохраненные данные, программист может предложить диалоговое окно сохранения, спрашивая их, хотят ли они сохранить, а не сохранить или отменить операцию.

В событии FormClosing, если они ударили Cancel, чтобы отменить заданную вами операцию e.Cancel = true;, Это отлично. Тем не менее, в меню, если пользователь нажимает Exit Кнопка то же самое должно произойти, кроме как вместо того, чтобы делать e.Cancel = true; это должно просто сделать return; потому что это ручка меню Click событие вместо FormClosing событие.

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

private void FrmEditorFormClosing(object sender, FormClosingEventArgs e)
{
    if (NeedsToSave)
    {
        DialogResult saveChangesDialog = 
MessageBox.Show("There are unsaved changes. Save now?", 
"Xml Editor", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);

        if (saveChangesDialog == DialogResult.Yes)
        {
            Save();
        }
        else if (saveChangesDialog == DialogResult.Cancel)
        {
            e.Cancel = true; // Only difference
        }
    }
}

private void ExitToolStripMenuItemClick(object sender, EventArgs e)
{
    if (NeedsToSave)
    {
        DialogResult saveChangesDialog = 
MessageBox.Show("There are unsaved changes. Save now?", 
"Xml Editor", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);

        if (saveChangesDialog == DialogResult.Yes)
        {
            Save();
        }
        else if (saveChangesDialog == DialogResult.Cancel)
        {
            return; // Only difference
        }
    }

    Close();
}

4 ответа

Решение

Вам не нужно этого делать. Вызов Close в вашем обработчике кликов меню должен вызвать событие FormClosing, и вы можете отменить его там.

Поместите общий код в метод, который возвращает логическое значение, чтобы указать, произошло ли сохранение

private bool PromptSave()
{
    if (NeedsToSave)
    {
        DialogResult saveChangesDialog = 
            MessageBox.Show("There are unsaved changes. Save now?", "Xml Editor",
            MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);

        if (saveChangesDialog == DialogResult.Yes)
        {
            Save();
            return true;
        }
        else if (saveChangesDialog == DialogResult.Cancel)
        {
            return false;
        }
    }
    else
    {
        return false;
    }
}

Используйте это возвращаемое значение для установки e.Cancel

Это должно быть довольно близко

private void ExitToolStripMenuItemClick(object sender, EventArgs e)
{
  if (DoSaveOnExit())
    Save();
  else
    return;
}  

private void FrmEditorFormClosing(object sender, FormClosingEventArgs e)
{
   if (DoSaveOnExit())
    Save();
   else
    e.Cancel = true;             
}
private bool DoSaveOnExit()
{
  if (NeedsToSave)
  {
     DialogResult saveChangesDialog = MessageBox.Show("T", "Xml Editor",
     MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);

    if (saveChangesDialog == DialogResult.Yes)
    {
        return true;
    }
    else if (saveChangesDialog == DialogResult.Cancel)
    {
        return false;
    }

}

Разделите его на другую функцию, которая возвращает логическое значение. Что-то вроде этого:

bool ConfirmSave()
{
    if (NeedsToSave)
    {
        DialogResult saveChangesDialog = MessageBox.Show("There are unsaved changes. Save now?", "Xml Editor",
                                                            MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);

        if (saveChangesDialog == DialogResult.Yes)
        {
            Save();
            return true;
        }
        else if (saveChangesDialog == DialogResult.Cancel)
        {
            return false; 
        }
    }
}

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

private void FrmEditorFormClosing(object sender, FormClosingEventArgs e)
{
    if(!ConfirmSave())
    {
        e.Cancel = true;
    }   
}

private void ExitToolStripMenuItemClick(object sender, EventArgs e)
{
    ConfirmSave();

    Close();
}
Другие вопросы по тегам