开发者

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

开发者 https://www.devze.com 2023-01-10 00:12 出处:网络
I have a custom windows modal form with the following event code: private void btnCancel_Click(object sender, EventArgs e)

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消