DialogResult требует два клика на ОК, когда форма модальная

У меня есть Child form который мне нужен Modalтак что конечно пользуюсь child.ShowDialog() сделать форму Modal, Хотя в этом form если пользователь выбирает close/cancel Кнопка они подсказаны DialogResult спрашивая, уверены ли они, что хотят закрыть. Проблема возникает, когда пользователь выбирает OK на DialogResult, Требуется два клика на OK для DialogResult box закрывать. Я обнаружил, что если я использую Dispose так же как Close Я могу сделать child form уйти по первому щелчку, но DialogResult box остается. Что мне не хватает в приведенном ниже коде, что позволит DialogResult box а также Form закрыть после одного нажатия на OK?

private void closeButton_Click(object sender, EventArgs e)
{
    if (calBackgroundWorker.IsBusy)
    {
        DialogResult dialogResult = MessageBox.Show("The Compass Calibration is already in progress, are you sure you wish to cancel?", "Stop Calibration", MessageBoxButtons.OKCancel);
        if (dialogResult == DialogResult.OK)
        {
            calibrationInProgress = false;
            calBackgroundWorker.CancelAsync();
            this.Dispose();
            this.Close();
        }
    }
    else
    {
        this.Close();
    }
}

2 ответа

Решение

С SiLo Ответ я смог получить гораздо дальше, но только DialogResult закроется, а не ChildForm, Чтобы оба были закрыты, мне нужно было добавить this.DialogResult = DialogResult.OK, Приведенный ниже код отлично работает для закрытия обоих Modal окна:

private void closeButton_Click(object sender, EventArgs e)
{
    if (calBackgroundWorker.IsBusy)
    {
        DialogResult dialogResult = MessageBox.Show("The Compass Calibration is already in progress, are you sure you wish to cancel?", "Stop Calibration", MessageBoxButtons.OKCancel);
        if (dialogResult == DialogResult.OK)
        {
            calBackgroundWorker.CancelAsync();
            this.DialogResult = DialogResult.OK;
        }
        return;
    }
    this.Close();
}

И обработчик событий:

void calBackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    if (e.Cancelled)
    {
        this.Close();
        return;
    }
}

Во-первых, вам не нужно Dispose() вызов, Close() достаточно. Тем не менее, ваш BackgroundWorker.CancelAsync() Вызов не собирается отменять задачу сразу (синхронно). Это зависит от реализации DoWork, но вы все равно получите RunWorkerCompleted событие, в котором вы можете обработать отмененный статус в.

Вы хотите что-то вроде этого:

void closeButtonClicked(object sender, EventArgs e)
{
  if(backgroundWorker.IsBusy)
  {
    var result = MessageBox.Show("...");

    if(result == DialogResult.OK)
      backgroundWorker.CancelAsync();

    return;
  }

  this.Close();
}

Тогда в вашем обработчике событий:

void RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
  if(e.Cancel)
  {
    this.Close();
    return;
  }
}
Другие вопросы по тегам