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