One Event handler for an array of checkboxes?

Mugsy's RapSheet 156 Reputation points
2022-05-09T21:41:08.177+00:00

I have an array of checkboxes and a form with multiple checkboxes on it. I want a counter that displays (in real time) how many are checked.

Rather than coding a duplicate "_CheckedChanged()" event for every single one, is there a way to have a single _CheckedChanged() even for the entire array?

> Private Sub frmMain_Load(...

>      Dim intChecked as Integer = 0

>      checkboxes = New CheckBox() {cbxTrackDefault, chkThumb01, chkThumb02, chkThumb03, ...

(What I've tried. DOESN'T WORK. Clearly, I don't know what I'm doing.)

> Private Sub CheckboxHandler(ByVal sender As CheckBox, ByVal e As System.EventArgs)

>     Dim position As Integer = 0

>     position = Array.IndexOf(checkboxes, checkboxes)

>     AddHandler checkboxes(position).CheckedChanged, AddressOf CheckboxHandler

>     If sender.Checked = True Then

>         intChecked += 1

>     Else

>         intChecked -= 1

>     End If

>     lblChecked.Text = intChecked

> End Sub

There must be a simple solution. Any assistance appreciated. TIA

VB
VB
An object-oriented programming language developed by Microsoft that is implemented on the .NET Framework. Previously known as Visual Basic .NET.
2,659 questions
0 comments No comments
{count} votes

2 answers

Sort by: Most helpful
  1. LesHay 7,126 Reputation points
    2022-05-09T23:56:36.673+00:00

    Hi
    Here is a stand alone example that may help. This is for dynamically adding Buttons but the principle is the same for most/any controls. It can easily be changed to add CheckBoxes if needed - just adjust the Properties being added. See line 26, where the same event handler is allocated to each Button.

    ' Blank Form1, copy/replace all
    ' default code with this code
    Option Strict On
    Option Explicit On
    Public Class Form1
      Dim pan As New Panel
      Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Size = New Size(500, 300)
        With pan
          .Location = New Point(5, 5)
          .Size = New Size(ClientSize.Width - 20, 220)
          .BackColor = Color.Beige
          .BorderStyle = BorderStyle.FixedSingle
        End With
        Controls.Add(pan)
        SetButtons(18)
      End Sub
      Sub SetButtons(num As Integer)
        Dim x As Integer = 2
        Dim y As Integer = 5
        Dim yStep As Integer = 30
        Dim cs As Integer = pan.Height
        For i As Integer = 1 To num
          Dim mybutton As New Button With {.Text = "Button" & i.ToString(), .Name = "Button" & i.ToString(), .Location = New Point(x, y), .BackColor = Color.LightGray, .AutoSize = True}
          pan.Controls.Add(mybutton)
          AddHandler mybutton.Click, AddressOf ButtonClick
          y += yStep
          If y + yStep >= cs Then
            x += 100
            y = 5
          End If
        Next
      End Sub
      Public Sub ButtonClick(sender As Object, e As EventArgs)
        Dim butt As Button = DirectCast(sender, Button)
        MessageBox.Show("Selected Button = " & butt.Name)
      End Sub
    End Class
    
    0 comments No comments

  2. Mugsy's RapSheet 156 Reputation points
    2022-05-10T01:12:19.807+00:00

    I found a nice simple solution (based on some code found here.)

    (see: "checkboxes" array defined in original question.)

    Right after the array assignment, I added:

    >         For intCnt = 0 To UBound(checkboxes)
    
    >             AddHandler checkboxes(intCnt).CheckedChanged, AddressOf _CheckedChanged
    
    >         Next
    

    Then, at the end of my code, I added the following Event Handler:

    >     Private Sub _CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs)
    
    >         If sender.checked Then
    
    >             For intCnt = 0 To UBound(checkboxes)
    
    >                 If checkboxes(intCnt) Is sender Then
    
    >                     intChecked += 1
    
    >                 End If
    
    >             Next intCnt
    
    >         Else
    
    >             intChecked -= 1
    
    >         End If
    
    >         lblChecked.Text = intChecked
    
    >     End Sub
    

    The "_CheckedChanged" event is now triggered no matter which checkbox is clicked (PROBLEM: checkboxes NOT in the array are triggered too.)

    I'll update my answer when I find a fix to ignore checkboxes not in the array.

    UPDATE: I found a (simplistic) way of ignoring other checkboxes simply by checking the "sender.Name" property in the "If/Then" (VB won't show it as an option in the popup, but it's valid.)

    If sender.checked And InStr(sender.name, "chkThumb") > 0 Then

    0 comments No comments