How to close a toplevel dialog and then change the toplevel view in the same thread(?)
See original GitHub issueBeen having this issue for a while but one of my linux users is unable to use my app cause when a modal dialog closes (essentially a ‘checking’ dialog), it never transitions to a new view. I’ve known about this issue for a while but it has not been a blocking issue, but it appears to now be. I can reproduce this issue.
In the above picture, I have the completion event of a long running task (this pic is after I tested a few methods - the MainIteration is not there originally). During this task, I have a MessageBox.Query() open with no buttons that says ‘Performing precheck’. When this process ends, the dialog is to close, and then either an error shows up, or a new UI controller (essentially full screen window) is swapped to.
On Windows, I’ve never seen any issues with this. On Linux I’m having lots of problems where the dialog disappears but the UI never changes. Debugging shows my swap code is called but the actual Run() event on my new UIController (which extends Window) is never fired. After more debugging, I found the the calls to Application.RequestStop() just request the top level stops, but the toplevel doesn’t change until… some time later, I guess.
How am I supposed to wait until all of these actions have been performed? In WinForms, if I recall, you could do Application.DoEvents() to let pump the UI queue. I see there is a MainLoop.MainIteration()
in Application.cs that seems like it should do the stuff I’m looking for. There’s a comment on it: /// while (main.EvensPending ()) MainIteration ();
When I use this, the MainIteration(); call is never invoked. Which makes me think there are no events pending. When calling Application.RequestStop() all it does is make the current TopLevel.Running = false. This has no setter logic so there is no way (I think) that an event pending is set. So this while method call would never work, I think.
You can see how I used it in the above picture, I just removed the while loop to try and force it to do a loop so the next TopLevel would be done after the current one is popped off the stack. This worked… sometimes(?).
I’m not really sure how I am supposed to wait until the latest TopLevel has been updated. This makes using dialogs difficult because I don’t really know when I can safely call Application.RequestStop() and Application.Run(). I’m trying to make sure all of these calls are invoked through MainLoop, but I’m not sure of the thread safety of this library (in WPF trying to UI things on the wrong thread would throw an exception. It might be useful to have that here so I don’t accidentally update the UI on the wrong thread?).
Issue Analytics
- State:
- Created 3 years ago
- Comments:5 (2 by maintainers)
Top GitHub Comments
Sorry for the long hiatus. Been really busy, lots of IRL stuff, and haven’t done much work on the Linux side of our project for several months. A cursory glance seems to indicate this is a lot of what I was looking for back when I was heavily working on it last year, so when my current work slows down, I’ll probably jump back onto the Linux system. I finally a system I can dedicate that doesn’t require use of a TV, which should make it much easier to test, but it will probably be a few months before my work begins to cool off.
@Mgamerz, I think I did what you requested. See this PR #1331.