Container Control Love

We are big fans of Container Controls for a lot of reasons.  Containers, in my opinion, are one of the most powerful tools in Xojo and they are often misunderstood and under used, in my opinion.

Complex UI

Complex UI

In the first picture you see a very complex layout.  The client only wanted a single window for everything.  Each item in the family list is its own container.  Each of those containers has a tab control and you can see a fairly typical layout.  In almost every case each of the tabs has its own container as well.  The project takes it to the extreme but adding these dynamically is really fast.

Screen Shot 2014-02-15 at 2.06.15 PMThis project was a conversion from VB6 and everything really was in one window.  It was a nightmare to debug and in the process of converting it and breaking it apart into containers we found numerous errors they had never been able to find due to the shear amount of code in this one window.  To load the container we simply create a new instance of one (if it doesn’t already exist), give it the database file and the container literally does everything else.  The Xojo window has about 200 lines of code for everything.  The old VB6 window had over 10,000 lines of code.

Containers let you create really complex UI layouts and treat it as a single entity.  I see this a lot with projects with tab controls where each tab has 30 controls on it and you have 10 tabs.  That’s a LOT of controls and logic to load and save the data to them.  What we do is create a container for each tab and the container has the load, validate and save logic.  Then we place the container on the tab control or page panel.

Doing things like this does a couple of things for us.  First, it makes the coding of the Window very simple.  Instead of having 300 controls you have 10.  When the Window is opened or when the user presses the tab to expose it to the user we tell it to load the data (this is where using ActiveRecord comes handy).  The window itself doesn’t know or care about the individual controls.  So all the code for the container is where it makes the most sense – in the container.

The second thing this does is simplify what the IDE has to display.  I’ve made no bones about it that I do not like the Xojo Navigator.  The more objects you have in it the worse it gets.  Finding stuff is hard and I find it to be a royal pain.  Using containers reduces this issue.

The only real drawback to using containers at this point is that they draw really slow in the Layout Editor.  This appears to be addressed in the latest 2014 R1 beta but until it’s actually shipped you never know if it will get pulled for some as yet undiscovered show stopper bug.

Containers are also the only reasonable way to make repeating rows of controls.  Many people bag on Xojo for not having a powerful grid component but I think by using Containers you can do a lot of the same things.  To make a very sharp repeating rows control you need to have at least 4 different containers.  The overall container, an inner bounds container, the overall list of rows, and finally the row itself.  This is for desktop apps only since you can do the same thing in Web with only two containers.

Doing this type of repeating row control is not possible in carbon apps since the controls do not respect the container bounds but it works in Cocoa apps.  In Windows there is no issues but in Linux you need to use the new transparent property on all of the containers so the controls will respect the bounds of the container.  Xojo just did a blog post on this.

The drawback to the repeating row strategy is that you don’t want to have hundreds or thousands of rows.  Each container consumes memory and they can quickly make your UI slow and unresponsive.  At that point it’s much better to page your data so that your user can only see x number of rows at a time.  We usually settle on 50 as a nice starting point.

As I said earlier, Web Edition repeating row lists are even easier.  You simply add the container row to the container list and it knows to add a scrollbar.  It also knows how to scroll when the user uses the mouse scroll wheel.

One caveat about this is WebDialogs.  There is a super nasty bug in the framework where WebDialogs don’t get events like they should.  If your web dialog, and subsequent container, happens to be over a WebListbox and you try to scroll, the underlying listbox will receive the scroll events.  If you find this happening to you, you can try disabling the listbox.  Still, this bug sucks.

There is huge overhead using the EmbedWithin method in web apps.  Every time you use it the app has to serve up a new page and send it down the pipe.  I saw an example project the other day that had 50 rows and each row had 10 container cells on it.  With very little data and no style information it took almost have a second to display the repeating list in the browser on the same machine.  Add some additional time going over a slower connection and your app looks slow and unresponsive.

The answer for now, is to not do that.  The performance of the embed within command is simply too big to use it a lot.  We had one largish web project where we used containers for each of our tabs and were adding them at runtime.  It was not good.  The lag time was simply too big so we ended up embedding the containers into the page at design time.  Now we take a little bit of a hit when the page is first displayed but the user doesn’t notice anything when they switch tabs.

If you are not using containers you really might want to look at them again.  They really are powerful tools.  With a little time and practice you can make your coding life easier while developing some incredibly complex layouts.

3 thoughts on “Container Control Love

  1. Bob, after reading this, I had one of those A-Ha moments. I have been using Canvases as ContainterControls for years now, not realizing I am using the wrong control. I would hear experts like you meantion ContrainerControl and my warp mind would change that to Canvas.

    Now I have several places I need to go back and change the code to CCs. Thank you! it will make my life much easier in the future.


  2. Glad I can help Scott. I’ve actually working on an idea for desktop apps that uses containers for a grid but only enough for the visible area. The control then will ask the user for the data for each row.

    Sadly, container performance for Web Edition probably means it won’t happen but we’ll see.

    Regardless, still very preliminary.

  3. Funny, reading the select case code above, I had to chuckle. The “ah ha” moment for me was doing exactly what you did there… allowing for the ability to swap out a GUI based on the users navigation — and how easy it was in Xojo using containers.

Comments are closed.