mono / xwt

A cross-platform UI toolkit for creating desktop applications with .NET and Mono
MIT License
1.37k stars 241 forks source link

Unrecoverable error when using Show() on dialog when it's already visible #528

Open DevChive opened 9 years ago

DevChive commented 9 years ago

Issue: Unrecoverable error when calling the Show() method on a dialog when it is already visible. Even placing try/catch around "this.Show();" does not allow for recovery.

Comments: Yes, i understand standard coding practices. However, it is best to be able to recover from errors and assist the (novice) developers.

Error: ShowDialog can be called only on hidden windows. Version: 0.1.0_2015-05-27 (master)

Sample: (pesudo code)

// Program.cs
  var dlg = new LoginDialog();
  dlg.Run();
  // -=-=-
  // LoginDialog.cs
  public LoginDialog()
  {
    // InitializeComponetns();
    this.Show();      // <--- This will ERROR OUT because, "dlg.Run();" is already showing it
  }

Suggested Fix: File: Xwt.WPFBackend\DialogBackend.cs

    // LINE 119:  Error @ LINE 124 "Window.ShowDialog();"
    public void RunLoop (IWindowFrameBackend parent)
    {
      if (parent != null)
        Window.Owner = ((WindowFrameBackend) parent).Window;
      Window.WindowStartupLocation = WindowStartupLocation.CenterOwner;
      try {
        Window.ShowDialog();
      } catch (Exception) { }
    }
sevoku commented 9 years ago

Why do you call Show() inside the constructor?

sevoku commented 9 years ago

And your fix simply eats all exceptions. It should at least catch the appropriate Exception which causes the error, if it is not possible to work around it. From my experience there are no "unrecoverable" exceptions (well besides of some weird multithreading cases). So if a try/catch helps then there must be a better workaround.

DevChive commented 9 years ago

The above is just a quick snippet as an example to uncover the bug

sevoku commented 9 years ago

Well, ok. But it still doesn't explain what exactly happens (which Exception is thrown?) and why you call Show() in the constructor. Can you gist a real example then, so one can reproduce the problem?

It should not be necessary to call Show() at all. dlg.Run does everything for you (see the Windows sample in the examples app). Show/Hide is only there to show hide the dialog window while dlg.run is running, so it can be useful in some complex situations, but not for eg. a simple login dialog. And if it is necessary in your situation, then you shouldn't use it in the constructor, since the dialog does not "really" exist inside the constructor.