I am trying to have a list of checkboxes with different values that then will populate into a multi-line textbox based on the selection. I will need to have the list be dynamic between users checking and unchecking boxes and having these populate by their selection into this textbox.
Any direction will help thanks!
I do not have a solution for this aright now
CodePudding user response:
You can list multiple controls after the "Handles" keyword in an event handler. In this case, we want to handle the CheckChanged event of your CheckBoxes. Note the multiple ControlName.Event
entries separated by commas after "Handles":
Public Class Form1
Private Sub AnyCheckBox_CheckedChanged(sender As Object, e As EventArgs) _
Handles CheckBox1.CheckedChanged, CheckBox2.CheckedChanged, CheckBox3.CheckedChanged,
CheckBox4.CheckedChanged, CheckBox5.CheckedChanged, CheckBox6.CheckedChanged
Dim cbs() As CheckBox = {CheckBox1, CheckBox2, CheckBox3, CheckBox4, CheckBox5, CheckBox6}
Dim values As New List(Of String)
For Each cb As CheckBox In cbs
If cb.Checked Then
values.Add(cb.Text)
End If
Next
TextBox1.Text = String.Join(Environment.NewLine, values)
End Sub
End Class
Within that handler, that fires when any of the CheckBoxes is changed, I create an Array of the CheckBoxes invovled. Now you can iterate over them in order and add their value to a List(Of String)
if it is checked. When done, we simply put all the values from the list together separated by newlines and assign the resulting string to the multiline TextBox.
The above should be easy to understand, but here is an alternate approach that keeps the Array at class/form level so it is only created once. Instead of using "Handles" it wires up the events using AddHandler
. Additionally, it uses LINQ to extract the selected values:
Public Class Form1
Private cbs() As CheckBox
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
cbs = {CheckBox1, CheckBox2, CheckBox3, CheckBox4, CheckBox5, CheckBox6}
For Each cb As CheckBox In cbs
AddHandler cb.CheckedChanged, AddressOf AnyCheckBox_CheckedChanged
Next
End Sub
Private Sub AnyCheckBox_CheckedChanged(sender As Object, e As EventArgs)
Dim values = cbs.Where(Function(cb) cb.Checked).Select(Function(cb) cb.Text)
TextBox1.Text = String.Join(Environment.NewLine, values)
End Sub
End Class
CodePudding user response:
An efficient way of doing this is to create an extended CheckBox class which can then be hooked up to the TextBox. This puts the add/remove logic in the extended class, and no additional code needs to be added to the form.
Create a new Class.
Public Class CheckBoxExtended
Inherits CheckBox
Public Property TextBox As TextBox
Public Sub New()
AddHandler Me.CheckStateChanged, AddressOf CheckStateChangedEventArgs
End Sub
Private Sub CheckStateChangedEventArgs(ByVal sender As Object, ByVal e As EventArgs)
If TextBox Is Nothing Then Return
Select Case CheckState
Case CheckState.Unchecked
TextBox.Text = TextBox.Text.Replace($"{Text}{Environment.NewLine}", "")
Case CheckState.Checked
TextBox.Text = $"{Text}{Environment.NewLine}"
End Select
End Sub
End Class
After building the project, the new control will be available in the toolbox in the designer. Add them to the form and make sure you hook-up the textbox to the control (in the properties):
I would however recommend using a ListBox (instead of a TextBox), where you can use the Items collection. This would change the extended class to:
Public Class CheckBoxExtended
Inherits CheckBox
Public Property ListBox As ListBox
Public Sub New()
AddHandler Me.CheckStateChanged, AddressOf CheckStateChangedEventArgs
End Sub
Private Sub CheckStateChangedEventArgs(ByVal sender As Object, ByVal e As EventArgs)
If ListBox Is Nothing Then Return
Select Case CheckState
Case CheckState.Unchecked
ListBox.Items.Remove(Text)
Case CheckState.Checked
ListBox.Items.Add(Text)
End Select
End Sub
End Class
Note that both these approaches have the limitation that the checkbox text must be unique, as it removes all instances of the text.