How to remove Container Controls "EmbeddedWithin" a Canvas

Embedding a few Container Controls within a Canvas seems to work OK but I also need to destroy them as well.

Have tried theContainer.Close then theContainer = nil but they just keep accumulating in the Canvas and of course their Paint events continue to Paint them. I have an array of these Containers in the Window and can Remove them from the array OK.

Any wise thoughts on what’s happening here … ?

PS: There appears to be other issues with the stability/predictability of the EmbedWithin command as per my additions to Feedback Case #2026.

as long as you have references to them closing them should be fine

You’ll need to close them and remove them from the array.

This code happily embeds a Container Control into a Canvas …

dim n as Node  // This is a Container Control 
n.EmbedWithin(Window1.Canvas1, 0, 0)

I was expecting the following code would destroy the reference to the Container and so destroy the associated EmbeddedWindow Control …

n.close
n = nil

But no … the embedded control lives on! Can anybody explain what I’m missing here?

[quote=62421:@Ian Ramsay]This code happily embeds a Container Control into a Canvas …

dim n as Node  // This is a Container Control 
n.EmbedWithin(Window1.Canvas1, 0, 0)

[/quote]
N is a local variable here

[quote=62421:@Ian Ramsay]
I was expecting the following code would destroy the reference to the Container and so destroy the associated EmbeddedWindow Control …

n.close
n = nil

But no … the embedded control lives on! Can anybody explain what I’m missing here?[/quote]
where is this code ?
How is “n” set ?
What control instance does it refer to ?

try this

  1. create a new desktop app
  2. make the window 600w x 500h
  3. add a canvas & make it top = 60, left = 20, width 560, height 420
  4. add a bevel button and make it top = 20, width = 60, height 22
  5. add a container control to the project called containercontrol1
  6. make the container control 230 w x 190 h
  7. add a lane l to the container (so we can identify it) doesn’t matter where
  8. add a property to Window1 - n as ContainerControl1
  9. add an open event to Window1 with the following code

[code] n = new ContainerControl1

n.EmbedWithin( Canvas1 , 10, 10 )[/code]
10) add the Action event to the bevel button on Window1 with the following code

if n <> nil then
  n.close
  n = nil
end if

Run & press the button

Hi

Thanks for your clarity on this matter. Here’s small testbed app that forces the behaviour you suggest above.

https://www.dropbox.com/s/nz45uociakpyctg/tstObj.xojo_binary_project

It has buttons to Create, Embed etc. and reports the state of the ContainerControl1.

There are a few curiosities to notice.

  1. The line cc = new ContainerControl1 if executed while cc already points to an EmbeddedWindowControl seem to leave the EmbeddedWindowControl dangling without a reference while constructing a whole new ContainerControl1 that after EmbedWithin will point to a second EmbeddedWindowControl. Any thoughts …

  2. The EmbedWithin works OK the first time round, but if I embed the same object instance twice it somehow Paints it further down inside the parent WindowCanvas1. Any thoughts …

  3. Even when a Window.Refresh is forced after destroying the ContainerControl1 bits of the container disappear (its own inner Canvas1) but other bits (its outline) remain on the screen till the Window is resized. Looks like one has to explicitly go clean up the graphics as well as the objects themselves. Any thoughts …

[quote=62437:@Ian Ramsay]1. The line cc = new ContainerControl1 if executed while cc already points to an EmbeddedWindowControl seem to leave the EmbeddedWindowControl dangling without a reference while constructing a whole new ContainerControl1 that after EmbedWithin will point to a second EmbeddedWindowControl. Any thoughts …
[/quote]
That’s the expected behavior. When you embed the container, the window acquires a reference to it, so if you drop your reference, the window’s reference keeps it alive. You just lose control over it.

[quote]2. The EmbedWithin works OK the first time round, but if I embed the same object instance twice it somehow Paints it further down inside the parent WindowCanvas1. Any thoughts …
[/quote]
You can only embed a container once. Doing it twice would be considered a bug in your code and the results will be unpredictable.

Can’t reproduce it on Windows 7, Xojo 20134.1. I did notice you’re using an alpha channel when you draw the outline. Have you tried it without transparency? Did you try refreshing the canvas instead of the window?

What Tim said. BTW, why are you embedding the Containers into a Canvas?

Here is an example project that might help.

OK … So this is all starting to make good sense. Need to be diligent so as to maintain a reference to the embedded container, then I can destroy it at will.

Will tinker with the alpha channel and see if that’s why the rePaint is not behaving as expected.

To Paul’s question, I am embedding the containers in a canvas for two reasons.

  1. I need an overall component that can be dragged taking all the embedded components along, and I don’t think Rect allows this.
  2. The overall component needs a transparency / fill property for usability / contrast and a Graphic property for some fiddly bits.

I could do 2) in the Window, but I think a Canvas is the only way to accomplish 1). Does this seem right, or might I be cooking up more problems?