Как закрыть пользовательский диалог без отображения графических артефактов? - PullRequest
0 голосов
/ 04 августа 2010

У меня есть пользовательская модальная форма Windows со следующим кодом события:

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

Проблема в том, что когда я нажимаю кнопку ОК, это вызывает некоторые трудоемкие вещи (генерация отчета), и форма становится частично нарисованнойна экране.Как будто генерация отчета имеет приоритет над обновлением окна.Есть ли что-то еще, что мне нужно сделать, чтобы заставить его исчезнуть перед интенсивным процессом кода?Это определенно будет раздражать моих пользователей.

РЕДАКТИРОВАТЬ # 1:

Я пытаюсь использовать метод Тергивера и передать владельца диалога 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 и дескриптор ненулевой.Есть еще идеи, как получить активную форму текущего процесса?

EDIT # 2 Сейчас я использую следующий код для извлечения активной формы и затем вызываю Owner.Refresh ()в событии OnFormClosed.

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 Ответ

3 голосов
/ 04 августа 2010

Очевидный ответ - не выполнять интенсивный процесс кода в потоке пользовательского интерфейса.

Для выполнения задачи используйте BackgroundWorker или ThreadPool.

Добавлено

Если вы настаиваете на выполнении этого в потоке пользовательского интерфейса, вы можете использовать this.Owner.BeginInvoke для выполнения кода после его закрытия.

...