Creating a window owned by another window

I have a window (ParentWindow), which needs to open another window. The ParentWindow contains data that the second window manipulates. When the second window closes, it needs to go completely away and not exist or be referenced by anything else.

I tried two methods, neither of which really works, so I’m asking for advice on what’s the “correct” way to handle this.

My first method:

The ParentWindow has a property, MySecondWindow as SecondWindow. The SecondWindow has a weakref getter/setter (MyParentWnd) to ParentWindow so that it can access the data and controls in the parent window. There can be only ONE SecondWindow at any given time.

When the ParentWindow needs to open the second window, it does:

   Self.MySecondWindow = New SecondWindow      'Self is the parent window
   NewSecondWindow.MyParentWnd = Self               'This is the reference the second window uses to access the parent
   Self.MySecondWindow.Show                                     'Show the second window

The problem with this is that when the second window closes, the parent still has a reference to it, even though the second window has no controls and isn’t visible. If the parent needs to open another second window, it can’t tell whether the second window still exists or not except by checking to see if Self.MySecondWindow has any controls.

My second method:

The ParentWindow has a weakref getter/setter (MySecondWindow), and the second window has a weakref to the parent.

When the ParentWindow needs to open the second window, it does:

 if Self.MySecondWindow <>nil then
      Self.MySecondWindow.Close
end if

Self.MySecondWindow = nil       'because just closing the window doesn't nil the reference to it

 dim SW as new SecondWindow
 Self.MySecondWindow = SW
 Self.MySecondWindow.MyParentWnd = Self
 SW.Show

The problem with this version is that when the user closes the second window, the parent’s weakref comes nil, but the second window may still exist, though not be visible or have controls.

Thoughts? Suggestions?

Seems to me when the WeakRef is nil, the second window has actually been destroyed.

However, if you have doubts about the window being really gone, you could use the kind of code in the example at
http://documentation.xojo.com/index.php/runtime

Which lists all existing objects.

IMHO. the best way to handle such a situation is to create a new class for your data. Then the first window passes the class instance to the 2nd Window, the 2nd Window performs its magic on the instance and returns it to the first window. If it’s possible to structure your data in that manner, you can dispense with all of the weak references etc.

I think maybe my description wasn’t too clear - the data is actually in a class separate from all the windows, but it’s “owned” by one specific window that displays most of its content. The other windows do reporting or manipulating of the data.

The hard part is that there can only be one of the “other” windows open onto the data at any given time (in addition to the parent window), so the parent window needs a clean and reliable way to know whether to refer the user to an existing window, or to create a new one. I don’t want to open one of every possible window at startup and just show/hide them as needed, there are probably a hundred of them and I’d rather conserver memory by closing them completely when they’re not needed (most are used for a very specific task and so are rarely used).

The WeakRefs should do that, but I’ve found they don’t always go nil. Maybe there’s some other reference somewhere that’s hanging onto the window they refer to…

I don’t see the problem. Your main window can still “own” the class instance, pass that instance to other windows as needed, and recollect the massaged data. To my way of thinking, you’re making this more complex that it needs to be.

So that leaves the question of knowing when one of the “other” windows has been created.

Instead of my current method should I put flags into the class instance to track when one of the “other” windows is managing the data, and clear the flag when the window closes?

Not knowing the structure of your data, that seems like a possible approach

[quote=260179:@John McKernon]
The WeakRefs should do that, but I’ve found they don’t always go nil. Maybe there’s some other reference somewhere that’s hanging onto the window they refer to…[/quote]

make sure you have turned implicit instances OFF

[quote=260182:@John McKernon]So that leaves the question of knowing when one of the “other” windows has been created.

Instead of my current method should I put flags into the class instance to track when one of the “other” windows is managing the data, and clear the flag when the window closes?[/quote]
Why should this matter ?
Its not like you have multiple threads all changing the data simultaneously
If all the windows are referring to the same instance then they are all sharing one instance
Maybe you just need to know IF one of the sub windows has changed something so the main window updates when those changes happen ?

Instead of holding references to the other window, you should loop through the list of open windows and look for the one you want. If you find it, return a reference to it. If you don’t find it, create one and return that.

dim sw as SecondWindow
sw = GetSecondWindow
sw.xyz = abc
Function GetSecondWindow as SecondWindow
    for i as integer = 0 to WindowCount-1
        if window(i) ISA SecondWindow then return SecondWindow(window(i))
   next
   return New SecondWindow
End Function

[quote=260196:@Norman Palardy]Its not like you have multiple threads all changing the data simultaneously
If all the windows are referring to the same instance then they are all sharing one instance
[/quote]

That’s true, but the real problem is not knowing whether I should open a new window or simply show the already-existing one.

I’ll try looping through the open windows, that sounds like it should work for sure, though an added complication is that the app can handle multiple sets of data, each with it’s own parent window. Since each dataset has a UUID, I’ll add that as a property to each open window as part of its constructor so that I can find the ISA SecondWindow belonging to the correct dataset.

I found the solution, by solving a problem I hadn’t noticed.

The WeakRef solution works great, HOWEVER what I hadn’t realized is that at some point in the process I did this:

  • I created a WeakRef in the ParentWindow to point to the SecondWindow. That’s good!

  • I created a WeakRef in the SecondWindow pointing to the ParentWindow. This is BAD, because it prevents the SecondWindow from closing completely. The window closes visually, and all of its controls are destroyed, but the window itself hangs around because of the two weakrefs referring to each other. It seems to me that the controls shouldn’t be destroyed, but that’s the reality.

I must have done this years ago and never noticed or realized that two weakrefs could hang onto each other.

Lesson learned, problem solved!

Thank you for your suggestions, which prompted me to really LOOK into the code and see what was happening.

Do you still have implicit instances enabled ?
If so turn it off

I never use implicit instances.

if you see the window still around after you close it “something else” is holding a non-weak reference to it

Yes, see my previous entry where I discovered there two weakrefs pointing at each other, that’s what was keeping the window from fully closing.

two weakrefs wont do this

there’s “something else”

I just whipped up a sample that used weakrefs between the two windows and closed one then the other & there are no instance of windows left in the runtime object list. they’re gone as are their controls

So what could cause a window to close visibly, all of its controls to become nil, and yet the window itself remains in memory?

Do you have a reference to any of its controls?

Nope, and if I did, that one control would still be on the window when it “closes”, right? In this case, there’s nothing left on the window.

My guess is there’s some property of the window that is holding onto it, but simply eliminating the two-way refs allowed the window to close completely.

You sure it’s a weakref? If so, that’s a bug.