Messaging back to a Window from which a Modal Window Opened

The foremost Window has a Control (a Button) that opens a Modal Window. Is there a way for that Modal Window to send back a message to the foremost Window that called it (in my use case change a public Property of that foremost Window?) How would I refer to that foremost Window?

Or do I have to mediate this message through some global value that both windows would have access to.

An easy way is to have the parent window call a new Method in the Modal window which can just return the result

ModalWindow.ShowAndSetResult() as String
  self.showModal // shows the modal window, stops execution until the window is closed
  if self.result = "xyz" then
       return "User Cancelled"
  else
  ...
  end if

The parent window then simply does:

var mw as new ModalWindow
var result as string = mw.ShowAndSetResult()
if result = "xyzzy" then
...

Edit: fixed some bugs

2 Likes

Typically I would have a constructor for the Sub-window that is passed the parent window.

Store this in a WeakRef in order that the parent doesn’t hold a reference to the child and the child a reference to the parent, which will leak objects. With one WeakRef you can solve that problem.

1 Like

In Xojo, the ShowModal method DesktopWindow — Xojo documentation is the one situation in which the rule “Only one event at a time can be processed” is broken. ShowModal will stop the calling code, and allow other events to happen (such as Button.action, Window.Close, etc.) and then resume program flow.

So if you really just need a simple value returned, you can use my method. If you have a lot more data to manipulate, then @Ian_Kennedy 's idea is more complicated and powerful.

2 Likes

Also, in Xojo Web, there’s a different technique: You can drag an instance of a WebDialog WebDialog — Xojo documentation onto a WebPage, and then add event handlers to the Dismissed event. Since the WebDialog instance is part of the parent WebPage, you can access properties and methods of the WebPage very easily.

I don’t think there’s a similar way of handling Modal Dialogs on Desktop, is there?

Thanks. I learned something and would never have stumbled across this myself. I appreciate Ian’s contribution as well, although my needs were very simple so Mike’s solution works for me.

I could have communicated through some global variable but I like not having to create one.

Also note that after ShowModal returns, you can no longer access any of its controls, but you CAN access its properties.

w.ShowModal
a = w.property1
b = w.property2

So in the modal window set any properties you want the parent window to access before the modal closes.

2 Likes

So the Modal Window is now Closed but in some sense it lives forever with its properties accessible?

When, if ever, does it go out of scope or truly die?


I guess this is a silly question. I assume that it lasts as long as the Var that was declared as the New ModelWindow lasts.

Exactly. If you created it as a local variable, it doesn’t go out of scope until the method ends. Then it is truly gone. Its controls are gone, but its properties remain accessible,

Also note that after ShowModal returns, you can no longer access any of its controls, but you CAN access its properties.

That all depends upon how you close the modal window. If you use Hide, rather than Close, the window’s control remain available for use and the progress continues in the normal way.

To be clear in the button (or what ever control triggers ending the window) do not use Self.Close but instead use ‘Self.Hide’, everything will work the way it used to but controls stay available.

I didn’t believe that Hide would work like Close, but I tested it (macOS) and it does indeed work that way.

The documentation says

“Displays the window and causes the current method to stop executing until the window closes or becomes invisible.”

so I guess “becomes invisible” is the same as “is hidden”

Yes, it does. It is likely due to matching the behaviour of VB versions up to version 6 (after that I’ve no idea). It’s a good trick if you don’t want to add lots of code to fill properties. It does mean you break the encapsulation of the window by having control code in the calling window, which is less than desirable.

1 Like