Dynamically Embed Container Controls - Requesting Code Critique

Hi,
I have this code working for embedding container controls on a scrolling canvas. However, I only have always used two types of container controls and both were of the same height.

I would like to add the ability to embed another container control object which contains a listbox. This object will be a different height. So, I was wondering if someone could critique my current code to help point me in the right direction of handling embedding container control objects of varying heights.

I realize this isn’t the best code and my comments on how I understand it may not be correct.

Thank you

[code]Sub CCAdd(oContainer As MyScrollViewCC)
// Add the newly created containter to the array of containers
aroContainers.append oContainer

// Check if we need to auto scroll before we embed the new container on the canvas.
//
// If our array of containers contains less containers than the maximium number
// of containers the canvas can display at one time, then set the scroll bar position to 0.
//
// If our array of containers contains more containers than the maximium number
// of containers the canvas can display at one time, then set the scroll bar position down
// to expose the amount of space in pixels needed on the canvas to handle the height of
// one more container.

dim y, offset as integer

container_height = oContainer.height
max_containers = ( self.height \ container_height ) - 1 // maximum # of displayable containers

// y is also where our top container in our list will be. Thats what we want our scrollbar
// to be set to. It points to the top most container.

y = Max( 0, ( aroContainers.Ubound * container_height ) - ( max_containers * container_height ) )

ScrollAutoScrollTo y

if y > 0 then
offset = max_containers * container_height
else
offset = aroContainers.Ubound * container_height

end if

// Add the container to the scroll view canvas
oContainer.embedwithin( self, 0, offset )
oContainer.TabIndex = aroContainers.Ubound

RaiseEvent ScrollViewCCAdded( oContainer )
RaiseEvent ScrollViewChanged

self.Invalidate
End Sub
[/code]

[code]Sub CCRemove(oContainer as MyScrollViewCC)
// Remove the container from the scroll view canvas

Dim i, y, newidx as Integer

RaiseEvent ScrollViewCCRemoved( oContainer )

// Remove specific container from our array of specific containers
i = aroContainers.IndexOf( oContainer )
aroContainers(i).Close
aroContainers.Remove(i)

// Set the new container to adjust our scroll to when we auto scroll
// Set this to one container before the container the user removed.
newidx = Max ( 0, ( i - 1 ) )

// Reposition specific containers
For i = 0 To aroContainers.Ubound
aroContainers(i).Top = i * container_height + self.Top - YScrollLast
aroContainers(i).TabIndex = i
Next

// Check if we need to auto scroll
//
// If our array of containers contains less containers than the maximium number
// of containers the canvas can display at one time, then set the scroll bar position to 0.
//
// If our array of containers contains more containers than the maximium number
// of containers the canvas can display at one time, then set the scroll bar position down
// to expose the amount of space in pixels needed on the canvas to handle the height of
// one more container.

// y is the total pixels our array (up until our newidx element) of containers are over what the canvas can hold in pixels.
// y is also where our top container in our list will be. Thats what we want our scrollbar
// to be set to. It points to the top most container.
y = Max( 0, ( newidx * container_height ) - ( max_containers * container_height ) )

ScrollAutoScrollTo y

RaiseEvent ScrollViewChanged

self.Invalidate
End Sub
[/code]

What I do in these situations like this is have the Add/Remove methods simply add it to the array and embed/remove the container as necessary. Then I call another function that sets their new top position based on their position in the array. This method handles variable height containers and it puts all the positioning code into a single method rather than 2 (or 3 if you have an insert).

Also, for what it’s worth, the array mirrors the position in the list. So if I’m appending the container it gets appended to the array, inserted into the array, removed from the array, etc.

I try to mimic built-in methods as much as possible to avoid confusion later. And by later I mean 6 months from now when you have to back and modify it.

You’re on the right track.

I thought I had to scroll the canvas to the insertion point for the control and then embed it. Are you saying I can just embed all the controls one right after another, on top of each other and then go back and reposition everything using a separate method?

Thank you

Yes. You can embed them all and change their coordinates later.

Thanks for your help Bob.

Since I have buttons that allow the user to add and remove the containers, I decided to clean up the mess of code that I had. I posted it below.

[code]Sub CCAdd(oContainer As MyScrollViewCC)
dim lastIndex, ccTop as Integer

lastIndex = aroContainers.Ubound
if lastIndex >=0 then
ccTop = (aroContainers(lastIndex).Top + aroContainers(lastIndex).Height) - self.top
end if

// Add the newly created containter to the array of containers
aroContainers.append oContainer

// Add the container to the scroll view canvas
oContainer.embedwithin( self, 0, ccTop )
oContainer.TabIndex = aroContainers.Ubound

myScrollbar.Maximum = Max( 0, ((ccTop + oContainer.Height + MyScrollBar.Value) - self.Height) )

RaiseEvent ScrollViewCCAdded( oContainer )

SetButtons()

self.Invalidate
End Sub
[/code]

[code]Sub CCRemove(oContainer as MyScrollViewCC)
Dim i, idx, ccTop as Integer

RaiseEvent ScrollViewCCRemoved( oContainer )

ccTop = oContainer.Top

// Remove container from our array of containers
idx = aroContainers.IndexOf( oContainer )

aroContainers(idx).Close
aroContainers.Remove(idx)

// Reposition the containers
For i = idx To aroContainers.Ubound
aroContainers(i).Top = ccTop
aroContainers(i).TabIndex = i
ccTop = ccTop + aroContainers(i).Height
Next

myScrollbar.Maximum = Max( 0, ((ccTop + MyScrollBar.Value) - self.Height) )

SetButtons()

self.Invalidate
End Sub
[/code]