0

My Winforms app has a MainForm and a MainWaitForm. For some reason I don't understand, my MainForm keeps being sent behind other opened windows, mainly when users click on anything when the MainWaitForm is showing... For example, when running the app in VisualStudio debugger mode, the wait dialog shows but VisualStudio comes right behind, instead of leaving the MainForm right on second level.

Here is the code of the wait form overlay :

static Control _parent;
public static void ShowWaitForm(Control parent) {
    _parent = parent;
    // some attempt to bring the active view to front first...
    if (_parent != null && _parent.Visible) {
      _parent.BringToFront();
    }
    else {
      MyMainForm.BringToFront();
    }
    // Make sure it is only launched once.
    if (_instance != null) {
      return;
    }
    _thread = new Thread(new ParameterizedThreadStart(MainWaitForm.ShowForm));
    _thread.IsBackground = true;
    _thread.SetApartmentState(ApartmentState.STA);
    _thread.Start(parent);
    while (_instance == null || _instance.IsHandleCreated == false) {
    System.Threading.Thread.Sleep(100);
    }
}

// the hide method
 public static void HideWaitForm() {
  // again, attempt to bring form to front...
  if (_parent != null && _parent.Visible) {
      _parent.BringToFront();
  }
  else {
      MyMainForm.BringToFront();
  }
  if (_instance != null) {
    if (_instance.InvokeRequired) {
      _instance.Invoke(new System.Windows.Forms.MethodInvoker(delegate {
        CloseForm();
      }));
    }
    else {
      CloseForm();
    }
  }
}

static void CloseForm() {
  _instance.Close();
  _thread = null;
  _instance = null;
}
neggenbe
  • 1,697
  • 2
  • 24
  • 62
  • because if the form is not Modal then whenever you click anywhere else it will go to the back.. try opening your form with .ShowDialog() method try that – MethodMan Nov 27 '17 at 18:02
  • using `_thread.SetApartmentState(ApartmentState.STA);` is absolutly the wrong thing to do, you are not fulfiling the STA contract because you don't have a message pump. You should get rid of the thread do do this with timers to loop and check. – Scott Chamberlain Nov 27 '17 at 18:39
  • You cannot steal the foreground back when your user gets tired of waiting. Feature, not a bug. Consider NotifyIcon.ShowBalloonTip() to notify him. Only create UI on a second thread when you can do [this kind of debugging](https://blogs.msdn.microsoft.com/dsui_team/2012/10/31/debugging-windows-forms-application-hangs-during-systemevents-userpreferencechanged/), stay out of trouble by running slow code on a worker thread and leaving up to the main thread to display UI. – Hans Passant Nov 27 '17 at 19:09
  • @HansPassant I've tried the background worker but performance is terrific compared to main thread (the task is to sync data with DB)... Any comment on that? – neggenbe Nov 28 '17 at 07:51

0 Answers0