Вопрос

I have a Child form which I need Modal, so of course I use child.ShowDialog() to make the form Modal. While in this form if the user selects the close/cancel button they are prompted by a DialogResult asking if they are certain they wish to close. The problem occurs when the user selects OK on the DialogResult. It requires two clicks on OK for the DialogResult box to close. I found that if I use Dispose as well as Close I can make the child form go away on the first click, yet the DialogResult box remains. What am I missing in the code below that will allow the DialogResult box and Form to close after one click on 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

With SiLo answer I was able to get much further, but only the DialogResult would close, not the ChildForm. To allow both to be closed I needed to add this.DialogResult = DialogResult.OK. The below code works perfectly for closing both Modal windows:

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();
}

And the Event Handler:

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

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

First, you do not need the Dispose() call, Close() is sufficient. However, your BackgroundWorker.CancelAsync() call is not going to cancel the task immediately (synchronously). That is up to the implementation of DoWork, but you will still get a RunWorkerCompleted event which you can handle the cancelled status in.

You want something like this:

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

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

    return;
  }

  this.Close();
}

Then in your event handler:

void RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
  if(e.Cancel)
  {
    this.Close();
    return;
  }
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top