Question about Container Control

I’ve got a container control that needs to call a method on a listbox that’s part of the container controls parent window. The parent window is called MainWindow. The listbox is called lstItemsInOrder. I need to call the listbox’s AddRow method.

I tried putting

MainWindow.lstItemsInOrder.AddRow("Test")

in the Action() of the container controls button I want to use to trigger the update but the code doesn’t see the listbox.

What is the proper way to so this? And yes, I’ve dragged an instance of the container control onto the MainWindow.

Thanks!

MainWindow(Me.Window).lstItemsInOrder.AddRow("Test")

I am unsure I really understand your question. BUT I try an answer:

To access the Listbox, I would use dot dot .

cc_LB.lstItemsInOrder.MethodName ()

cc is the name of the ContainerControl

cc_LB.lstItemsInOrder.AddRow("") ?

The above only if you put a ContainerControl on the window and place lstItemsInOrder in that ContainerCOntrol, then drag it into your window (MainWindow).

IMHO, this is the proper way using Xojo:
In your CC, create a new Event Definition. Add a parameter which will be the item to be added to the LB. now go to the instance of your CC in mainWindow and choose to add an event. You will
see the Event you just create listed as an option. Put the code to add the item to the LB here. Your LB will be recognized since this code resides in the mainWindow. Finally, in your CC, when you get the item to be added, call
RaiseEvent myNewEvent(myLBObject)
In this way, whatever window the CC is added to can receive this event and handle it correctly.

This is the correct way if your container control shall be a reusable one for any window. If the container control is tied to be used in one specific window, it adds unnecessary complexity and casting the parent or window property is the better way.

Example for the first case: a “lookup” container control, consisting of a text field and a button on the right for calling a lookup window (an “enhanced combobox” for a multi-column database lookup window).

Example for the second cases: the container control will exist exactly one time – you just use it because else there are way too many controls in the window and you can’t manage them reasonably in the navigator. Or a parent / child listbox container control, where the child class is a container control only to be used within the same parent (like the rows in NSPredicateEditor for complex searches in the Mac Finder).

I agree with Roger’s method, and normally that would be the way I would go about it.
Another option would be to add a reference to the list box in the container control, so you could access the listbox from within the container control without the need for casting.

Eli: I disagree. Using the Event Definition feature of Xojo does not add complexity but rather simplification to the messy deal of calling back to the parent from a child object.

Calling a method or property on the parent is a one-line statement and hardly a “messy deal” compared to defining an event (one line), raising it (another statement), and then implement the event (three lines).It is really only necessary if the class must be reusable for more than one specific window. Doing it the “Xojo way” in any case, just because it is possible, is in my opinion wrong.

To argue my reasoning, I defer to one more knowledgeable than I. It was at a talk by Guyren Howe at the 2008 Real World in Austin that I first learned about this powerful Xojo (then RealBasic) feature. His book on the matter, Object Oriented Programming with REALbasic, out of publication)
Relevant Logic LLC, outdated in technical points but still quite valid on technique, explains the reasons for avoiding calling up to a parent object far better than I could.

A change I’d make to Rogers technique is to have the event return the listbox. The CC knows what it wants to do to the listbox, it just needs reference to it. Don’t spread work out to the parent.

[code]ContainerControl MyCC

EventDef Function GetListboxToActOn() As Listbox

Sub process()
dim lb As Listbox = RaiseEvent GetListboxToActOn //use the event to get the lb
lb.AddRow(“Test”) //then work on it in the CC
End Sub

End ContainerControl

Window MainWindow

Listbox myLB

MyCC MyCC1
Event Function GetListboxToActOn() As Listbox
return myLB
End
End

End Window[/code]

I agree with Eli, that if this only needs that 1 tether then a 1 line cast isn’t bad. And if you realize it does need to be reused with other types it’s easy to switch in an event later.

Why don’t you put the Listbox into the ContainerControl, then moves a copy to the window ?