ListBox and ComboBox
Master list-based controls in Visual Basic 2026 — add, remove, search and select items dynamically, bind to data sources, and build real-world applications like a task manager and country selector with GitHub Copilot assistance.
Items collection with identical methods — learn one and you know both. In VB 2026 / .NET 10, both controls also support data binding directly to collections and LINQ query results.
Control Quick Reference
6.1 Working with the ListBox Control
The ListBox displays a scrollable list of items. Users can click to select one item (or multiple items if SelectionMode is set to MultiSimple or MultiExtended). Items can be added at design-time via the Properties Window, or at runtime in code.
Adding Items at Design-Time
In the Visual Studio 2026 designer, select the ListBox, find the Items property in the Properties Window, and click the … button to open the String Collection Editor. Type each item on its own line and click OK.
Adding Items at Runtime — Example 6.1
Public Class Form1 Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load ' Add items one at a time lstLanguages.Items.Add("Visual Basic 2026") lstLanguages.Items.Add("C#") lstLanguages.Items.Add("Python") lstLanguages.Items.Add("JavaScript") lstLanguages.Items.Add("TypeScript") ' AddRange is faster for multiple items — adds them all at once lstLanguages.Items.AddRange({"Java", "Kotlin", "Swift"}) ' Select the first item by default lstLanguages.SelectedIndex = 0 End Sub Private Sub btnShowSelected_Click(sender As Object, e As EventArgs) Handles btnShowSelected.Click If lstLanguages.SelectedIndex = -1 Then MsgBox("Please select an item first.", MsgBoxStyle.Exclamation, "No Selection") Return End If lblSelected.Text = $"You selected: {lstLanguages.SelectedItem}" End Sub Private Sub btnRemove_Click(sender As Object, e As EventArgs) Handles btnRemove.Click If lstLanguages.SelectedIndex <> -1 Then lstLanguages.Items.RemoveAt(lstLanguages.SelectedIndex) End If End Sub Private Sub btnClear_Click(sender As Object, e As EventArgs) Handles btnClear.Click lstLanguages.Items.Clear() lblSelected.Text = "" End Sub End Class
Multi-Selection ListBox — Example 6.2
Setting SelectionMode = MultiExtended lets users hold Ctrl to select multiple items, or Shift to select a range. Read all selected items by iterating SelectedItems:
' Set at design-time: lstItems.SelectionMode = SelectionMode.MultiExtended Private Sub btnShowAll_Click(sender As Object, e As EventArgs) Handles btnShowAll.Click If lstItems.SelectedItems.Count = 0 Then lblResult.Text = "No items selected." Return End If ' Build a comma-separated list of all selected items Dim selected As IEnumerable(Of String) = lstItems.SelectedItems.Cast(Of String)() lblResult.Text = $"Selected ({lstItems.SelectedItems.Count}): {String.Join(", ", selected)}" End Sub
Click items to toggle selection (simulating Ctrl+Click multi-select). Then click Show Selected.
6.2 Working with the ComboBox Control
The ComboBox is ideal when you have many options but limited screen space. It shows only the selected item until the user clicks the dropdown arrow. The DropDownStyle property controls its behaviour:
| DropDownStyle | Behaviour | User Can Type? |
|---|---|---|
| DropDown | Dropdown list + editable text field (default) | ✅ Yes |
| DropDownList | Dropdown list only — user must pick from list | ❌ No |
| Simple | Always-visible list with editable text field above | ✅ Yes |
Example 6.3 — ComboBox with Load, Add, and Remove
Public Class Form1 Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load ' Populate at startup cboVersion.Items.AddRange({"VB 2026", "VB 2022", "VB 2019", "VB 2017", "VB 2015", "VB 6"}) cboVersion.SelectedIndex = 0 ' Default to first item ' Auto-complete as user types cboVersion.AutoCompleteMode = AutoCompleteMode.SuggestAppend cboVersion.AutoCompleteSource = AutoCompleteSource.ListItems End Sub Private Sub BtnAdd_Click(sender As Object, e As EventArgs) Handles BtnAdd.Click Dim newItem As String = InputBox("Enter new item:", "Add Item") If String.IsNullOrWhiteSpace(newItem) Then Return If cboVersion.Items.Contains(newItem) Then MsgBox($"'{newItem}' already exists in the list.", MsgBoxStyle.Information) Else cboVersion.Items.Add(newItem) cboVersion.SelectedItem = newItem ' Select the newly added item End If End Sub Private Sub BtnRemove_Click(sender As Object, e As EventArgs) Handles BtnRemove.Click Dim itemToRemove As String = InputBox("Enter item to remove:", "Remove Item") If cboVersion.Items.Contains(itemToRemove) Then cboVersion.Items.Remove(itemToRemove) Else MsgBox($"'{itemToRemove}' was not found.", MsgBoxStyle.Exclamation) End If End Sub Private Sub cboVersion_SelectedIndexChanged(sender As Object, e As EventArgs) Handles cboVersion.SelectedIndexChanged ' Fires every time the selection changes lblSelected.Text = $"You chose: {cboVersion.SelectedItem} (index {cboVersion.SelectedIndex})" End Sub End Class
6.3 Practical Application — Task Manager
This example combines a TextBox for input, a ListBox for task display, and buttons for Add, Remove and Clear — a complete mini task manager demonstrating how these controls work together in a real application.
Public Class TaskManager Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load Me.Text = "Task Manager" ' Pre-load some sample tasks lstTasks.Items.AddRange({"Buy groceries", "Finish VB 2026 lesson", "Call the dentist"}) UpdateTaskCount() End Sub Private Sub btnAdd_Click(sender As Object, e As EventArgs) Handles btnAdd.Click Dim task As String = txtTask.Text.Trim() If String.IsNullOrEmpty(task) Then lblStatus.ForeColor = Color.Red lblStatus.Text = "⚠ Please enter a task." Return End If If lstTasks.Items.Contains(task) Then lblStatus.ForeColor = Color.OrangeRed lblStatus.Text = "⚠ This task already exists." Return End If lstTasks.Items.Add(task) txtTask.Clear() txtTask.Focus() lblStatus.ForeColor = Color.DarkGreen lblStatus.Text = $"✔ Added: {task}" UpdateTaskCount() End Sub Private Sub btnRemove_Click(sender As Object, e As EventArgs) Handles btnRemove.Click If lstTasks.SelectedIndex = -1 Then lblStatus.ForeColor = Color.OrangeRed lblStatus.Text = "⚠ Select a task to remove." Return End If Dim removed As String = lstTasks.SelectedItem.ToString() lstTasks.Items.RemoveAt(lstTasks.SelectedIndex) lblStatus.ForeColor = Color.Gray lblStatus.Text = $"Removed: {removed}" UpdateTaskCount() End Sub Private Sub btnClear_Click(sender As Object, e As EventArgs) Handles btnClear.Click lstTasks.Items.Clear() lblStatus.ForeColor = Color.Gray lblStatus.Text = "All tasks cleared." UpdateTaskCount() End Sub ' Helper — keeps the task count label updated Private Sub UpdateTaskCount() lblCount.Text = $"Tasks: {lstTasks.Items.Count}" End Sub ' Press Enter in the TextBox to trigger Add Private Sub txtTask_KeyPress(sender As Object, e As KeyPressEventArgs) Handles txtTask.KeyPress If e.KeyChar = Chr(13) Then btnAdd.PerformClick() End Sub End Class
6.4 New in VB 2026 / .NET 10 — Data Binding
In Visual Basic 2026 with .NET 10, both ListBox and ComboBox support direct data binding to generic collections (List(Of T)) and LINQ query results. This is far cleaner than manually calling Items.Add() in a loop, and the list updates automatically when the underlying collection changes (if using BindingList(Of T)).
Imports System.ComponentModel Public Class Form1 ' BindingList automatically reflects changes back to the ListBox Private _tasks As New BindingList(Of String) Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load _tasks.Add("Buy groceries") _tasks.Add("Finish VB 2026 lesson") _tasks.Add("Call the dentist") ' Bind the list directly — no Items.Add() loop needed lstTasks.DataSource = _tasks End Sub Private Sub btnAdd_Click(sender As Object, e As EventArgs) Handles btnAdd.Click ' Add to the BindingList — ListBox updates automatically! _tasks.Add(txtTask.Text.Trim()) txtTask.Clear() End Sub Private Sub btnRemove_Click(sender As Object, e As EventArgs) Handles btnRemove.Click If lstTasks.SelectedIndex >= 0 Then _tasks.RemoveAt(lstTasks.SelectedIndex) End If End Sub ' Filter with LINQ — bind filtered results to a second ListBox Private Sub txtSearch_TextChanged(sender As Object, e As EventArgs) Handles txtSearch.TextChanged Dim filtered = _tasks.Where(Function(t) t.ToLower().Contains(txtSearch.Text.ToLower())).ToList() lstFiltered.DataSource = filtered End Sub End Class
When you set lstTasks.DataSource = _tasks where _tasks is a BindingList(Of T), any additions or removals to _tasks in code are instantly reflected in the ListBox — no manual Items.Add() or refresh calls needed. For read-only snapshots, a plain List(Of T) works fine but won't auto-update.
6.5 GitHub Copilot — ListBox & ComboBox Assistance
Generate a Populated ComboBox from a Comment
' Populate cboCountry with all Southeast Asian countries and set Malaysia as default'' Populate cboCountry with all Southeast Asian countries and set Malaysia as default cboCountry.Items.AddRange({ "Brunei", "Cambodia", "Indonesia", "Laos", "Malaysia", "Myanmar", "Philippines", "Singapore", "Thailand", "Vietnam" }) cboCountry.SelectedItem = "Malaysia" cboCountry.AutoCompleteMode = AutoCompleteMode.SuggestAppend cboCountry.AutoCompleteSource = AutoCompleteSource.ListItems
Generate a Live Search Filter
' Filter lstProducts as user types in txtSearch — case-insensitive'' Filter lstProducts as user types in txtSearch — case-insensitive Private _allProducts As New List(Of String) Private Sub txtSearch_TextChanged(sender As Object, e As EventArgs) Handles txtSearch.TextChanged Dim query = txtSearch.Text.ToLower() Dim filtered = _allProducts. Where(Function(p) p.ToLower().Contains(query)). ToList() lstProducts.DataSource = filtered End Sub
Try these in the Copilot Chat panel while working on ListBox/ComboBox projects:
- "Move the selected item up one position in lstTasks"
- "Sort lstItems alphabetically when a Sort button is clicked"
- "Save all ListBox items to a text file and reload them on startup"
- "Bind cboProduct to a List(Of Product) showing the Name property"
📘 Lesson Summary
- The ListBox shows all items at once in a scrollable area; the ComboBox shows only the selected item until the dropdown is opened — both share identical
Itemscollection methods. - Add items at runtime with
Items.Add()for one item orItems.AddRange()for many at once (faster — avoids multiple redraws). - Check
SelectedIndex = -1before readingSelectedItemto avoid a NullReferenceException when nothing is selected. - Use
Items.Contains()before adding to prevent duplicate entries. - Set
SelectionMode = MultiExtendedon a ListBox to allow Ctrl+Click and Shift+Click multi-selection; read all picks viaSelectedItems. - The
SelectedIndexChangedevent fires every time the selection changes — use it for live updates without a button. - Set
AutoCompleteMode = SuggestAppendon a ComboBox to give users autocomplete as they type — a professional UX improvement requiring just two property lines. - In VB 2026 / .NET 10 use
DataSource = myBindingListfor automatic two-way synchronisation — no manualItems.Add()loops needed. - GitHub Copilot can generate complete ListBox population, filtering, and item management code from a single descriptive comment.
Exercises
Exercise 6.1 — Programming Language Selector
- Create a ComboBox pre-loaded with 8 programming languages
- When a language is selected, display its description in a Label (e.g. "Python — general-purpose, beginner-friendly")
- Add an Add to Favourites button that copies the selected language to a separate ListBox
- Prevent duplicates in the Favourites list using
Items.Contains() - Copilot challenge: Ask Copilot to "add a Remove from Favourites button and save the list to a text file"
Exercise 6.2 — Shopping Cart
- Create a ListBox of available products with prices (e.g. "Laptop — RM 3,200")
- Add an Add to Cart button that moves the selected item to a Cart ListBox
- Display the running total price in a Label that updates every time an item is added or removed
- Add a Remove Item button and a Clear Cart button
- Show item count and total with string interpolation: "3 items — Total: RM 4,500"
Exercise 6.3 — Live Search Filter
- Load 20 country names into a ListBox on Form_Load using
Items.AddRange() - Add a TextBox above it — as the user types, filter the ListBox to show only matching countries
- Use a
List(Of String)as the master data source and rebind viaDataSourceon TextChanged - Show the match count below the ListBox: "Showing 3 of 20 countries"
- Copilot challenge: Ask Copilot to "make the search also highlight matching text in the ListBox items"
Related Resources
← Lesson 5
Working with Controls — TextBox, Label, validation and data conversion.
Lesson 7 →
PictureBox — loading and displaying images in Windows Forms.
ListBox Docs
Official Microsoft reference for the Windows Forms ListBox in .NET.
ComboBox Docs
Official Microsoft reference for the Windows Forms ComboBox in .NET.
Featured Books
Visual Basic 2022 Made Easy
Covers ListBox, ComboBox and all essential Windows Forms controls with step-by-step projects and clear explanations.
View on Amazon →
VB Programming With Code Examples
48 complete VB.NET programs — study real-world list control applications including inventory managers and selection forms.
View on Amazon →