Home
Search
 
What's New
Index
Books
Links
Q & A
Newsletter
Banners
 
Feedback
Tip Jar
 
C# Helper...
 
XML RSS Feed
Follow VBHelper on Twitter Follow VBHelper on Twitter
 
 
 
MSDN Visual Basic Community
 
 
 
 
 
TitleUse a tristate CheckBox to let the user select all or none of a group of other CheckBoxes in Visual Basic .NET
DescriptionThis example shows how to use a tristate CheckBox to let the user select all or none of a group of other CheckBoxes in Visual Basic .NET.
Keywordscontrols, ComboBox, tristate, tri-state, indeterminate, Visual Basic .NET, VB.NET
CategoriesControls
 

The example Use a tristate CheckBox in Visual Basic .NET explains how to use a tristate CheckBox. This example demonstrates a particularly common usage: allowing the user to select all or none of a set of other CheckBoxes.

In this example:

  • If you check the Meals CheckBox, the program checks the Breakfast, Lunch, and Dinner CheckBoxes.
  • If you uncheck the Meals CheckBox, the program unchecks the Breakfast, Lunch, and Dinner CheckBoxes.
  • If you check or uncheck the Breakfast, Lunch, or Dinner CheckBoxes, the program makes the Meals CheckBox checked, unchecked, or indeterminate appropriately.

The most confusing part of this program is the way the CheckBoxes interact with each other. For example, suppose you check the Breakfast CheckBox. The code must then update the Meals CheckBox. If the Lunch and Dinner choices are not checked, the program makes the Meals CheckBox indeterminate and its CheckStateChanged event handler fires. The program must then update the states of the Breakfast, Lunch, and Dinner CheckBoxes so their event handlers fire. The process continues in a fairly confusing manner until eventually all of the CheckBoxes' states are set to unchecked when they are already unchecked. At that point, the states do not change so the event handlers don't fire. The program doesn't get stuck in a loop but the CheckBoxes are always unchecked. (Try commenting out the IgnoreCheckChangeEvents code descriebd shortly and use the debugger to see what happens.)

To solve this problem, the program uses a Boolean variable named IgnoreCheckChangeEvents. The event handlers check this variable and don't do anything if it is True.

The following code shows how the example responds when the user clicks the Meals CheckBox.

 
' True if we should ignore check change events.
Private IgnoreCheckChangeEvents As Boolean = False

' Select or deselect all CheckBoxes.
Private Sub chkMeals_CheckStateChanged(ByVal sender As _
    System.Object, ByVal e As System.EventArgs) Handles _
    chkMeals.CheckStateChanged
    If (IgnoreCheckChangeEvents) Then Return

    If (chkMeals.CheckState = CheckState.Indeterminate) Then
        chkMeals.CheckState = CheckState.Unchecked
    End If

    Dim meal_boxes() As CheckBox = {chkBreakfast, chkLunch, _
        chkDinner}
    IgnoreCheckChangeEvents = True
    For Each chk As CheckBox In meal_boxes
        chk.Checked = chkMeals.Checked
    Next chk
    IgnoreCheckChangeEvents = False
End Sub
 
The event handler first checks IgnoreChangeEvents and, if it is True, returns.

Next if the Meals CheckBox has the indeterminate state, the code changes it to Unchecked. This prevents the user from selecting the unchecked state by directly clicking on the Meals CheckBox.

Next the code loops through the Breakfast, Lunch, and Dinner CheckBoxes making their Checked states match that of the Meals CheckBox. To prevent those controls' event handlers from reacting, the code sets IgnoreCheckChangeEvents to True before changing the Checked states and sets it to False after it is done.

The following code shows how the program reacts when the user clicks the Breakfast, Lunch, or Dinner CheckBoxes.

 
' The user changed a meal type selection.
' Update the chkMeals CheckBox.
Private Sub chkMealType_CheckedChanged(ByVal sender As _
    System.Object, ByVal e As System.EventArgs) Handles _
    chkBreakfast.CheckedChanged, chkLunch.CheckedChanged, _
    chkDinner.CheckedChanged
    If (IgnoreCheckChangeEvents) Then Return

    ' See how many meals are selected.
    Dim num_selected As Integer = 0
    Dim meal_boxes() As CheckBox = {chkBreakfast, chkLunch, _
        chkDinner}
    For Each chk As CheckBox In meal_boxes
        If (chk.Checked) Then num_selected += 1
    Next chk

    ' Set the chkMeals CheckBox appropriately.
    IgnoreCheckChangeEvents = True
    If (num_selected = 3) Then
        chkMeals.CheckState = CheckState.Checked
    ElseIf (num_selected = 0) Then
        chkMeals.CheckState = CheckState.Unchecked
    Else
        chkMeals.CheckState = CheckState.Indeterminate
    End If
    IgnoreCheckChangeEvents = False
End Sub
 
If the program should ignore check change events, the code returns.

Next the code loops through the meal CheckBoxes, counting those that are selected. If all of the meals are selected, the program sets the Meals CheckBox's state to Checked. If none of the meals are selected, the program sets the Meals CheckBox's state to Unchecked. Finally if some meals are selected and others are not, the code sets the Meals CheckBox's state to Indeterminate. The code uses the IgnoreCheckChangeEvents variable to prevent the Breakfast, Lunch, and Dinner CheckBoxes from reacting when the code changes their states.

 
 
 
 
Copyright © 1997-2010 Rocky Mountain Computer Consulting, Inc.   All rights reserved.
  Updated