简体   繁体   中英

How do I get custom dialog close without showing graphics artifacts?

I have a custom windows modal form with the following event code:

private void btnCancel_Click(object sender, EventArgs e)
{
  Close();
  _result = DialogResult.OK;
}

The problem is when I click OK, that triggers some process-intensive stuff (report generation) and the form becomes partially drawn on the screen. It's like the report generation is taking precedence over the window refresh. Is there something else I need to do in order to get it to disappear before the process-intensive code? This will most definitely annoy my users.

EDIT #1:

I'm trying to work Tergiver's method and pass in the dialog owner to ShowDialog. For my case, the calling method is not a form. So, I'm trying to create a IWin32Owner from the process's main window handle so that I can pass it into the ShowDialog method.

public class WindowWrapper : System.Windows.Forms.IWin32Window
{
    public WindowWrapper(IntPtr handle)
    {
        _hwnd = handle;
    }

    public IntPtr Handle
    {
        get { return _hwnd; }
    }

    private IntPtr _hwnd;
}

// In calling method
ShowDialog(new WindowWrapper(System.Diagnostics.Process.GetCurrentProcess().MainWindowHandle));

However, the dialog owner is still not set after the call to ShowDialog. I stepped into the WindowWrapper and the handle is non-zero. Any more ideas as to how to get the current process's active form?

EDIT #2 I'm now using the following code to retrieve the active form and then calling Owner.Refresh() in the OnFormClosed event.

public static Form GetActiveForm()
{
  // Returns null for an MDI app
  Form activeForm = Form.ActiveForm;
  if (activeForm == null)
  {
    FormCollection openForms = Application.OpenForms;
    for (int i= 0; i < openForms.Count && activeForm == null; ++i)
    {
      Form openForm = openForms[i];
      if (openForm.IsMdiContainer)
      {
        activeForm = openForm.ActiveMdiChild;
      }
    }
  }    
  return activeForm;
}

// In code opening dialog.
ShowDialog(GetActiveForm());

The obvious answer is not to do process-intensive code on the UI thread.

Use a BackgroundWorker or the ThreadPool to do the task.

Added

If you insist on doing it on the UI thread, you could use this.Owner.BeginInvoke to execute code after this closes.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM