Container Control Reference

Hi.

I have created a Container Control with some text fields on it. An instance of this container is added to the form for each record in a database table.
But i cant display any data inside these textboxes because i cant reference the control names on the container.

On the container, there are 2 Text Fields, txt1 and txt2. I need to change the text displayed in these textfields either before or after they are added to the form.
This is my code for adding the container. The code is executed from a button at the moment.


  dim objMyContainer as ContainerControl

      objMyContainer = new MyContainer
      objMyContainer.EmbedWithin(Self, 10,  10, 25, 25)
      objMyContainer.Left = x
      objMyContainer.Top = y
      objMyContainer.Width = 250
      objMyContainer.Height = 250

This code will be repeated for each database record.
How do i change the text displayed in the textfields?
end if[/code]

Change your Dim to the type you really want:

Dim objMyContainer As MyContainer

Or, if you have a reason not to do that, cast your reference to MyContainer to access its specific controls, methods, etc:

MyContainer(objMyContainer).MyTextField.Text = "Hello"

Thanks for the quick reply. Changing the Dim was the problem.
That’s what i get for following tutorials :slight_smile:

If it’s something in our docs, let me know so I can get it updated.

I think it was on the old forum.
This is a great alternative to using listboxes. I can add an infinite amount of rows to my window, like a listbox.
Add controls that arent supported in list boxes, like combo boxes and make it look how i want!

[quote=24582:@Alex Ongley]I think it was on the old forum.
This is a great alternative to using listboxes. I can add an infinite amount of rows to my window, like a listbox.
Add controls that arent supported in list boxes, like combo boxes and make it look how i want![/quote]
You might not find container controls as flexible though.

You can’t create a “control set” of container controls, so you will have to individually add every instance you want to a window or pragmatically “embed within” every copy you want added instead of just spawning a copy from a control set.

Also, controls within a container are scoped within that container - if you have a label within a container control that, when added to a window you need to interact with another control on the window via an onclick event, you can’t.

The control added to the window is the container control, thus the only the container can be given events and interact with other controls added to the window - so when you create a new container control, any controls you add within it will have to have their events call a custom method (of the container) which in turn raises a custom event definition on that container, such as “Label_1_OnClick” just so you can have an onclick event for that label when the container is added to a window

[quote=24649:@Tony Stark]You might not find container controls as flexible though.

You can’t create a “control set” of container controls, so you will have to individually add every instance you want to a window or pragmatically “embed within” every copy you want added instead of just spawning a copy from a control set.
[/quote]
That’s the power - you can create them on the fly with NO preexisting instances
The IDE makes great use of this.

[quote=24649:@Tony Stark]Also, controls within a container are scoped within that container - if you have a label within a container control that, when added to a window you need to interact with another control on the window via an onclick event, you can’t.

The control added to the window is the container control, thus the only the container can be given events and interact with other controls added to the window - so when you create a new container control, any controls you add within it will have to have their events call a custom method (of the container) which in turn raises a custom event definition on that container, such as “Label_1_OnClick” just so you can have an onclick event for that label when the container is added to a window[/quote]

This forces you to REALLY think about the design instead of just poking at the innards of whatever you want.
This is a good thing.

[quote=24664:@Norman Palardy]That’s the power - you can create them on the fly with NO preexisting instances
The IDE makes great use of this.[/quote] While I personally prefer it that way, normal controls do not have this functionality (as far as im aware) which means you essentially have a control that has to be implemented differently. If normal controls were like this it would be great and the framework /GUI becomes more consistent.

[quote]This forces you to REALLY think about the design instead of just poking at the innards of whatever you want.
This is a good thing.[/quote]Not sure what you mean by this.

I recently had a project where I grouped a collection of controls that I had to duplicate multiple times. This allowed me to refer to the container instance and loop over the individual controls and pick out values as need be, using the same method for all of them but I also wanted simple interactions from those controls (within the container) with other controls on the window for those particular instances, which can’t be done “out of the box”.

I see that as a limitation of the IDE rather than “thinking about the design”.

Grouping a collection of controls under their own name space /object /class (containers) yet still having per-instance event coding I would say is basic functionality, unless I’m missing something? and it’s not like you cant have the functionality, it’s just a counter productive way over the general flow of the IDE as per current…

An IDE isn’t about going “Well you COULD have that feature, but we won’t add it because you SHOULD think about the design first”, instead it should be about integrating the development process and doing common tasks easier". Other IDE’s will rip the alpha channel from images or split images up into smaller ones, such as a large image mostly made up of an alpha, simply with elements plotted /positioned around.

You can go “hur dur, well you should think about the design and split the images up yourself and understand a bigger image requires more processing” but the IDE is the difference between making the process trivial Vs complex and time consuming, and since Xojo IDE is completely closed off and hard to expand upon, it’s not like we can even create our own dev /IDE tool for Xojo (and you’ve tried to contractually prevent us in our terms from doing this too due to fear of competition?)

Having the choice (and in this example: basic features), has nothing to do with problem solving (which is essential what programming has always been about). I’d say having to add events for controls in containers via an obscured way is a failing in Xojo’s design of containers, as such, container controls can become more complicated than they need to be, especially due to the human-management aspect of manually adding every event

That is all :slight_smile:

[quote=24697:@Tony Stark]While I personally prefer it that way, normal controls do not have this functionality (as far as im aware) which means you essentially have a control that has to be implemented differently. If normal controls were like this it would be great and the framework /GUI becomes more consistent.
[/quote]
Container controls ARE special in many ways - hence why they are different.

Well you could write your code as a HUGE set of global methods & all global variables but you don’t (well maybe you do but you shouldn’t)
Container controls require you to think about an API - what should be publicly accessible vs what should not be.
That’s a good thing - it helps you avoid bugs in the long run

[quote=24710:@Norman Palardy]Container controls require you to think about an API - what should be publicly accessible vs what should not be.
That’s a good thing - it helps you avoid bugs in the long run[/quote]I’m not sure if I understand that concept for this scenario though?

If it was a subclass control you’d add the event and, if you wanted the instance to be able to handle that event too, you would create an event definition, leaving you the option to use it or not for single instances. The option is there for you to choose based on what best for your design which means it may, or may not be used.

How would allowing that same level of flow be allowed as part of the IDE /framework as a core functionality, instead of manually linking be of harm? You’re simply making the manual linking less tedious (and avoid using 2 levels worth of pointless function calls hopefully?)

The mention of using globals makes me believe you are referring to the OO concept of keeping everything you need “near” and passing objects to each other, rather than accessing “things” from global points.

It’s not that you are saying it would be bad for controls’ events to be accessible to one level higher, only that you should use it only where appropriate (which applies to almost everything) - so whats stop xojo from simplifying the process in the IDE and bringing in consistency through controls (even if it is special).

Im guessing you could loop over the control, create events, methods and event definitions automatically with ide scripting, though? but still, the though of 2 pointless function calls is “urgh”.

It works exactly how i want it to.
4 containers are added to the window and they are hidden at first. They are only visible when there is data in the recordset to populate them.
If there are more records in the RS than can be shown, the user can scroll through the records using a scrollbar and the container controls are updated accordingly.
Database records are updated using the keyUp event for each of the container controls.

It has exactly the same functionality as a subform does in MS Access, which is what i wanted.
It looks more or less the same as a listbox, but it can do so much more.

Hi Alex, is it possible to show me some code or a sample on how to accomplish that. We come from Ms Access background and always wondering how to do this.

I have been working on this a little more recently and i have come up with something better. It replicates a MS Access subform. I have stopped using containers for this.
Create multiple rows of objects (i have 4) and add a scrollbar. Each row has 2 textFields and a textArea.
All 4 rows of objects are hidden by default. Create a recordSet and populate the rows. Un-hide the rows when necessary. If there are more than 4 records in the RS, enable the scroll bar and set the maximum value to the total number of records in the RS.
When the scrollbar is moved, get the scrollbar value (say 5) clear all row data, select the 5th record in the RS and repopulate the form, starting at record 5. Its actually quite simple and it looks like the controls are scrolling.

Select RS
Get record count from DB table
Populate first row:
Method - addNoteRecords

'If there is a record If rs.EOF = false Then 'Unhide row txtNoteComment2.Visible = true txtNoteDate2.Visible = true cboNoteInputBy2.Visible = true lblNoteDate2.Visible = true lblNoteInputBy2.Visible = true bvlDelete2.Visible = true 'Populate controls txtNoteComment2.text = rs.Field("comment").StringValue txtNoteDate2.Text = rs.field("date").StringValue cboNoteInputBy2.Text = rs.field("InputBy").StringValue 'Move to next record rs.MoveNext else 'If there is no record, hide row txtNoteComment2.Visible = false txtNoteDate2.Visible = false cboNoteInputBy2.Visible = false lblNoteDate2.Visible = false lblNoteInputBy2.Visible = false bvlDelete2.Visible = false end if

Repeat the last step for each row on the form.

Add this to scrollbar.valuechanged

'save value to variable
scrlFirst = ScrollBar1.Value
'pass variable to method
 addNoteRecords(scrlFirst)

We have done something very similar for our image list and thumbnails but instead of using scroll bar we have 2 image button for Previous and Next.

I will give your idea a try and let you know what is the outcome.

and thanks for the idea. Why don’t you use the container control way instead??

Seemed pointless in the end, glad i did it though because i learnt a lot.
Why programatically add controls when adding them normally gives the same result?

Plus, when i was adding the container controls, the screen flickered for some reason and the scrolling wasn’t as quick.

With the scrollbar, i have added a mouseWheel event to the window so you can scroll the form using that as well. Just an idea

[quote=26121:@Alex Ongley]Seemed pointless in the end, glad i did it though because i learnt a lot.
Why programatically add controls when adding them normally gives the same result?
[/quote]

First of all - if it works for you then do it, I am not going to tell you to try and do it a different way if the way that you are doing it works :slight_smile:

However to try and answer the more general use of Container Controls. A very common scenario, you have an explorer panel on the left of a window and a document area in the centre (and perhaps an inspector on the right hand side). You have a number of ‘things’ to explore, each is a different kind (class) of document, these could be recordsets, files, data from a device etc. You want to generalise the operation of the application window.

The user clicks on a ‘thing’ in the explorer and you want to show the ‘document’ relating to that thing, to make it more interesting you may want to have many documents open using a tabbed document area. So one approach is to create a sub class of Container Control, lay out the document using controls within the sub classed Container Control and hold/manage the document data within the Container Control.

Back to the user clicking on the ‘thing’, your explorer generates an event that the main window processes, the main window examines what the ‘thing’ is from what was supplied to the event, your main window creates an instance of the sub classed Container Control and embeds it within a newly created tab panel in the document area. So now your main window can access all of the ‘documents’ that were created and can iterate over them to provide for example a ‘Save All’ function by calling a save method on each container, etc… Documents can raise events back to the main window to for example update a status bar or update an inspector window.

This is an OO approach, but not just for the hell of it or because some academic proposes it. What is does is simplify and reduce the code in the main application window - now your sub classed containers do the work that is specific to the document and your main application window just coordinates the actions between the various composite parts of the UI. Another benefit is that when your application needs to support a new kind of ‘thing’ with an associated document, you create a new sub classed container and some new coordination code in the main window, sure you still have to write code but with the responsibilities of the various composite parts cleanly separated (and you are less likely to introduce new side effects/bugs for the existing documents).

HTH

Carl, it helps me. Great example.

Im glad its helped someone. Il upload a demo project when i’ve had time to finish it. Having a few problems with r2 at the moment…

is the demo ready yet??? would love to see how u did it, Alex