如何在不显示图形工件的情况下关闭自定义对话框?

时间:2010-08-04 14:19:11

标签: c# winforms refresh modal-dialog

我有一个带有以下事件代码的自定义窗口模式窗体:

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

问题是,当我单击“确定”时,会触发一些过程密集型内容(报告生成),并且表单会在屏幕上部分绘制。这就像报告生成优先于窗口刷新。为了让它在流程密集型代码之前消失,我还需要做些什么吗?这肯定会让我的用户感到烦恼。

编辑#1:

我正在尝试使用Tergiver的方法并将对话框所有者传递给ShowDialog。对于我的情况,调用方法不是表单。所以,我正在尝试从进程的主窗口句柄创建一个IWin32Owner,以便我可以将它传递给ShowDialog方法。

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

但是,在调用ShowDialog后仍未设置对话框所有者。我走进了WindowWrapper,手柄非零。关于如何获得当前流程的活动形式的更多想法?

编辑#2 我现在使用以下代码检索活动表单,然后在OnFormClosed事件中调用Owner.Refresh()。

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

1 个答案:

答案 0 :(得分:3)

显而易见的答案是不要在UI线程上执行过程密集型代码。

使用BackgroundWorker或ThreadPool来完成任务。

<强>加

如果您坚持在UI线程上执行此操作,则可以使用this.Owner.BeginInvoke在此关闭后执行代码。