|
|
Title | Use a tristate CheckBox to let the user select all or none of a group of other CheckBoxes in Visual Basic .NET |
Description | This 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. |
Keywords | controls, ComboBox, tristate, tri-state, indeterminate, Visual Basic .NET, VB.NET |
Categories | Controls |
|
|
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.
|
|
|
|
|
|
|
|
|