Building a container control for WinForms was easier than I first imagined. Why did I build one? Because I needed a custom solution for viewing controls that were created, but could not be placed into any other third-party control.
It appears that Microsoft left out the Data Repeater that was in VB 6 for Windows, so now we have to make our own.
Making the Container
The container is just a
UserControl. Some of the particulars are to set the
AutoScroll=True and add some events for handling which control is selected as well as the count.
Public ReadOnly Property Count() As Integer
Public ReadOnly Property SelectedItem() As ChildItem
The Container control is loaded by passing it a strong-typed collection.
Public Property Items() As SimpleItemCollection
Set(ByVal Value As SimpleItemCollection)
_Items = Value
If Value Is Nothing Then
Once the collection is passed in, you can load the control using the
LoadAll method in the custom control.
Private Sub LoadAll()
Dim n As Integer
Dim bSuspend As Boolean
Dim flipper As Boolean
Dim counter As Integer
_Loading = True
_SelectedChild = Nothing
_Top = 0
For Each item As SimpleItem In Me._Items
Dim itm As New ChildItem(item)
.Left = 0
.Width = Me.Width
.Top = _Top
_Top += itm.Height
If Not bSuspend Then
If _Top > Me.Height Then
bSuspend = True
AddHandler itm.ItemSelected, AddressOf ChildSelected
AddHandler itm.ItemDoubleClicked, AddressOf _
If Me.Count = 1 Then
_Loading = False
Me.AutoScrollHandler.VisibleAutoScrollHorizontal = False
Making the Child Control
The child control inherits from
Control. The reason for doing so is the reduced overhead of the
ScrollableControl and the
ContainerControl. There might be better ways to build this control, but I've found this to be sufficient and quick displaying. If you use a
UserControl as the child and set the
Top, it eases the loading code, etc., but it takes forever to resize the control and doesn't paint as fast.
The child control is simple and powerful once you get the hang of painting to the control. Get familiar with using the
Graphic class. Methods such as
Create a class that
Imports to the
Control to manage the
ComponentModel as well as the drawing.
There are some key style settings you need to add that are documented very little on the web. These settings manage the drawing and scrolling for the controls.
Public Sub New()
Me.BackColor = Color.White
Or ControlStyles.UserPaint _
Or ControlStyles.AllPaintingInWmPaint, _
When creating the control, which is handled by the Custom container, just pass in the
Contact (which in this example is the class object that holds the data for the control).
Public Sub New(ByVal item As SimpleItem)
_Contact = item
Me.Height = 40
Public ReadOnly Property Contact() As SimpleItem
Painting the child control is going to have to be managed by the code. Unlike the
UserControl class, this control does not paint itself. You lose the simplicity, but you gain speed when loading hundreds of controls. Plus, it's cool to impress friends and neighbors with your code! Yeah right.
Protected Overrides Sub OnPaint(ByVal pe As _
Dim ft As Font
If Not Me.Parent Is Nothing Then
ft = Me.Parent.Font
ft = New Font("Tahoma", 8, GraphicsUnit.Point)
& " " & Contact.LastName, ft, _
New SolidBrush(Me.Parent.ForeColor), 28, 6)
Now this is just a simple and rude example. You can get as elaborate as you want with painting the control. This is how the big-boys (third-party) do it.
Managing which item is selected is just a matter of trapping for
MouseDown and raising an event that tells the parent container, which in this instance is the Custom Container, that this item is selected to unselect all others and move
Me into view.
Private Sub pnlMain_MouseDown(ByVal sender As System.Object, _
ByVal e As System.Windows.Forms.MouseEventArgs) _
If e.Button = MouseButtons.Left AndAlso AllowSelect Then
Public Sub SetSelected()
Selected = True
Public Property Selected() As Boolean
Set(ByVal Value As Boolean)
_Selected = Value
If Value Then
BackColor = Color.Gainsboro
BackColor = Color.White
The example code has all you'll need to get started and expand upon.