Click here to Skip to main content
14,734,420 members
Articles » Web Development » User Controls » General
Posted 22 Feb 2012


82 bookmarked

Flexible List Control

Rate me:
Please Sign up or sign in to vote.
4.91/5 (58 votes)
7 Feb 2013CPOL
Building a list control that allows anything to be added to it.


In a normal listbox or listview control, you are bound with a lot of restrictions. You cannot add images or icons properly, cannot provide your own highlighting colors, or placement of text, and a most wanted feature is that you cannot add multiline text to the default list controls.

Today I will show you how to build a list control that shows list items just the way you want them to be. They can be multiline, or have images in them, various sizes of texts or background colors, complex placements of items in it, etc. Its all up to you how you design it. Complete flexibility!

Building The List Control

We're going to be using the default available controls to make this dream come true. I will show you how to make a list control, what you do with that list control is totally up to your imagination. So starting off we're going to make a list control having a FlowLayoutPanel control in it only.

Create a new project in your Visual Studio. Add a Usercontrol to your project and name it as ListControl.

On the ListControl place a FlowLayoutPanel and name it flpListBox.

Provide the following properties to the flpListBox:

  • AutoScroll = True
  • AutoSize = False
  • Dock = Fill
  • FlowDirection = TopDown
  • Margin = 0, 0, 0, 0
  • WrapContents = False

And provide following properties to the ListControl usercontrol:

  • BorderStyle = FixedSingle
  • Padding = 0, 0, 0, 0

Now we need to add code to the ListControl to handle the adding, removing, counting and clearing functions, just like any other list control. Therefore we will add four functions Add, Remove, Clear, and Count.

Public Sub Add(c As Control)

End Sub

Public Sub Remove(name As String)

End Sub

Public Sub Clear()

End Sub

Public ReadOnly Property Count() As Integer
        Return flpListBox.Controls.Count
    End Get
End Property

Let's add the code for the Add sub. As you can see in the definition the Add sub is accepting a control as a listitem, not text or any other kind of object. This is because we're going to create a flexible list control where any type of independent control can be added to it and the our ListControl will move it around just like any other list control.

Public Sub Add(c As Control)
End Sub

That was a simple code. It only adds your control (i.e. list item) to the flow layout panel. The flow layout panel has been told to add all the controls inside it from Top to Down manner. So all controls will be added vertically. You keep on adding controls and it will keep on appending it to the list of controls added to the flow layout panel. Now lets code for Remove and Clear subs.

Public Sub Remove(name As String)
    Dim c As Control = flpListBox.Controls(Name)
End Sub
Public Sub Clear()
        If flpListBox.Controls.Count = 0 Then Exit Do
        Dim c As Control = flpListBox.Controls(0)
End Sub

I want to discuss the Clear sub first here. In order to remove all the controls from your list control, there is a very easy way of doing it. Simply call the flpListBox.Controls.Clear and it will remove all the controls. But these controls still remain in the memory. It is up to your coding method or according to your programming needs, but I prefer my list control to dispose off the control as soon as I remove them from the list control. In order to do this first we need to grab the control from the flow layout panel, remove it from its control list and then finally dispose it off.

In the Clear sub the above process of disposing is repeated until all the controls from the list have been removed. But in Remove sub of course we only need to do this process once just for the control user has asked to remove.

Using The Control

Our ListControl is complete. You can trial run this control at this stage. Place ListControl on a new Form and add the following code to the Load event.

Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
    For i as Integer = 1 To 20
        Dim btn As New Button
        With btn
            .Name = "b" & i
            .Text = "Button " & i
            .Height = 25
            .Margin = New Padding(0)
        End With
End Sub

The above code will add twenty buttons to the ListControl. For each of those button you can hook a click event by AddHandler in your form's code.


The reason why I have set the Margin property of the buttons to zero is to reduce the line gap between each row in our list control.

Our ListControl is ready. It will automatically show the scroll bar whenever the items exceed the height of the list control. You can also scroll with mouse wheel. At the moment it does not handle resize events, in case you may want to resize your control to fit the width of ListControl.

Managing Size and Resize Event

By here our list control is complete. You may want to add uneven sized controls in it, its entirely up to you. You could even make something fancy like this:


Because it is a flow layout panel control it allows you to add anything to it and it will manage its placement by itself. But only placement, not the sizes. Size is defined by you.

In order to build a proper looking list control we need to automate the sizes as well here. For this the following code need to be added:

Private Sub SetupAnchors()
    If flpListBox.Controls.Count > 0 Then
        For i = 0 To flpListBox.Controls.Count - 1
            Dim c As Control = flpListBox.Controls(i)
            If i = 0 Then
                ' Its the first control, all subsequent controls follow
                ' the anchor behavior of this control.
                c.Anchor = AnchorStyles.Left + AnchorStyles.Top
                c.Width = flpListBox.Width - SystemInformation.VerticalScrollBarWidth
                ' It is not the first control. Set its anchor to
                ' copy the width of the first control in the list.
                c.Anchor = AnchorStyles.Left + AnchorStyles.Right
            End If
    End If
End Sub

Private Sub flpListBox_Layout(sender As Object, e As System.Windows.Forms.LayoutEventArgs) Handles flpListBox.Layout
    If flpListBox.Controls.Count Then
        flpListBox.Controls(0).Width = flpListBox.Size.Width - SystemInformation.VerticalScrollBarWidth
    End If
End Sub

We have added a subroutine called SetupAnchors. In a flow layout panel, if you set the anchor of a control to Left + Right, all controls inside it can have their own heights, but for widths they all adopt the width of the first control in the list. Whatever the width is of the first control, other controls will automatically follow. But the first control cannot have a Left + Right anchor. You have to manually define the width of the first control. This is how flow layout panel behaves by default.

So in above I have assigned a Top+Left anchor for the very first control in the list and all the other controls have Left+Right anchor. As a result all controls will follow the width of the first control. So whenever the ListControl is resized, it will resize the first control only (see flpListBox.Resize event) and other controls will automatically copy its width.

Accordingly amend the Add and Remove subs to call the SetupAnchors sub from them whenever a control is added or removed from the list.

Public Sub Add(c As Control)
End Sub
Public Sub Remove(name As String)
    Dim c As Control = flpListBox.Controls(Name)
End Sub

Taking It To Next Level

Since ListControl allows any kind of control to be added to it and it will handle it like any other list control item, you can even make custom user controls and add it to ListControl. In the first screenshot at the top of the page, I have created a custom usercontrol which manages its own highlighting and colors, text placement, icon and stars, etc. All ListControl does is add it to its list.

To achieve this lets make some improvements in the code that I've explained above. I've made some slight changes... now you don't have to create a new control to add to the list, the ListControl will do that for you. Its all according to your needs, really! You can turn, twist, twirl etc. with this control according to your application needs. You may embed everything inside the ListControl or manually create a new control and attach it.

I've built a list item control, called ListControlItem, that has the following properties: song name, artist name, album name, duration of song, image of the song or album, rating for the song.

Note: Since this article is only to demonstrate the possibilities of ListControl, I will not be explaining the code of ListControlItem. To see the code of ListControlItem download the sample project and have a look.

So I've changed the Add procedure like this:

Public Sub Add(Song As String, Artist As String, Album As String, Duration As String, SongImage As Image, Rating As Integer)
    Dim c As New ListControlItem
    With c
        ' Assign an auto generated name
        .Name = "item" & flpListBox.Controls.Count + 1
        .Margin = New Padding(0)
        ' set properties
        .Song = Song
        .Artist = Artist
        .Album = Album
        .Duration = Duration
        .Image = SongImage
        .Rating = Rating
    End With
    ' To check when the selection is changed
    AddHandler c.SelectionChanged, AddressOf SelectionChanged
End Sub

And the Remove procedure has been amended as:

Public Sub Remove(name As String)
    ' grab which control is being removed
    Dim c As ListControlItem = flpListBox.Controls(name)
    ' remove the event hook
    RemoveHandler c.SelectionChanged, AddressOf SelectionChanged
    ' now dispose off properly
End Sub

As I have added a hook to an event from ListControlItem to monitor when selection is changed, therefore when disposing the control it is an efficient programming practice to remove the hook as well.

And I've added another subroutine to ensure that only one list item is selected at a time:

Dim mLastSelected As ListControlItem = Nothing
Private Sub SelectionChanged(sender As Object)
    If mLastSelected IsNot Nothing Then
        mLastSelected.Selected = False
    End If
    mLastSelected = sender
End Sub

That's it!

Now when using the modified ListControl you don't need to create or dispose controls. All will be handled by itself. You can add items to the list this way from your Windows Form:

ListControl1.Add("Party Rock Anthem (feat. Lauren Bennett & GoonRock)", "LMFAO", "For DJs Only [2011]", "4:23", ImageList1.Images(7), 5) 

See Example Code

Our ListControl is finally complete. It may not be as memory efficient as the default listview or listbox control or any other third party listview control, but it works absolutely well and provides the flexibility that other list controls don't.

This little sample project is built to demonstrate the ListControl being used for a media player type application. It depends what type of application you're building. How the list item will look like is entirely up to you as you will be designing the list item, ListControl will only manage it in a list form.


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Faraz Azhar, Dubai
United Arab Emirates United Arab Emirates
No Biography provided

Comments and Discussions

GeneralThanks Faraz Azhar Pin
Member 1349610317-Apr-20 2:50
MemberMember 1349610317-Apr-20 2:50 
Questionhow to get Selected item Album name Pin
Member 1347054824-Feb-19 1:25
MemberMember 1347054824-Feb-19 1:25 
QuestionMulticolumn Pin
Cool Smith23-Feb-18 0:21
MemberCool Smith23-Feb-18 0:21 
GeneralMy vote of 5 Pin
MRezaK12-Nov-16 4:23
MemberMRezaK12-Nov-16 4:23 
SuggestionMissing the arrow keys focus Pin
Mazen el Senih1-May-15 5:54
professionalMazen el Senih1-May-15 5:54 
QuestionFlicker on (horizontal) resize Pin
Jens Madsen, Højby18-Jan-15 6:43
MemberJens Madsen, Højby18-Jan-15 6:43 
SuggestionNew version Pin
claudetom019-Oct-14 0:34
Memberclaudetom019-Oct-14 0:34 
GeneralRe: New version Pin
Faraz Azhar, Dubai9-Oct-14 20:01
MemberFaraz Azhar, Dubai9-Oct-14 20:01 
SuggestionRe: New version Pin
claudetom0110-Oct-14 7:29
Memberclaudetom0110-Oct-14 7:29 
GeneralRe: New version Pin
Faraz Azhar, Dubai12-Oct-14 2:47
MemberFaraz Azhar, Dubai12-Oct-14 2:47 
Question Pin
Member 1104518629-Aug-14 2:05
MemberMember 1104518629-Aug-14 2:05 
Questionhelp Pin
Member 1054310816-May-14 2:41
MemberMember 1054310816-May-14 2:41 
AnswerRe: help Pin
Faraz Azhar, Dubai13-Jun-14 1:28
MemberFaraz Azhar, Dubai13-Jun-14 1:28 
GeneralMy vote of 5 Pin
rspercy6514-Aug-13 9:45
Memberrspercy6514-Aug-13 9:45 
GeneralMy vote of 5 Pin
OAlpha27-Jun-13 0:45
MemberOAlpha27-Jun-13 0:45 
GeneralRe: My vote of 5 Pin
Faraz Azhar, Dubai29-Jun-13 23:13
MemberFaraz Azhar, Dubai29-Jun-13 23:13 
GeneralMy vote of 5 Pin
BertrandLQ13-May-13 10:56
MemberBertrandLQ13-May-13 10:56 
Questionlistbox Pin
Real Anon User11-May-13 4:26
MemberReal Anon User11-May-13 4:26 
AnswerRe: listbox Pin
Faraz Azhar, Dubai2-Jun-13 5:30
MemberFaraz Azhar, Dubai2-Jun-13 5:30 
QuestionHow to Get... properties of the item Pin
sebastianbg1-May-13 13:44
Membersebastianbg1-May-13 13:44 
AnswerRe: How to Get... properties of the item Pin
Faraz Azhar, Dubai2-Jun-13 5:32
MemberFaraz Azhar, Dubai2-Jun-13 5:32 
AnswerRe: How to Get... properties of the item Pin
Rodney Minter16-Oct-16 20:19
MemberRodney Minter16-Oct-16 20:19 
QuestionVertical Scroll Bar Pin
dblap30-Apr-13 3:46
Memberdblap30-Apr-13 3:46 
AnswerRe: Vertical Scroll Bar Pin
Faraz Azhar, Dubai2-Jun-13 5:54
MemberFaraz Azhar, Dubai2-Jun-13 5:54 
QuestionMaking the List control item change colors after selecting a higher star rating? Pin
dblap15-Apr-13 4:16
Memberdblap15-Apr-13 4:16 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.