Select All Controls on Form - vb.net

I am trying to implement a clear all button on a form that clears the textbox contents and unchecks all checkboxes. The issue is that the controls that need to be accessed are contained within Groupboxes and thus cannot be acessed via Me.Controls collection. I saw a similar post here: VB Uncheck all checked checkboxes in forms, but the answer seems to be more complex than I would expect it should be. Is there any easier way other than in that post.
I tried this code, which logically to me should work but it does not:
'Get textboes and clears them
For Each ctrGroupBoxes As Control In Me.Controls.OfType(Of GroupBox)
For Each ctrControls As Control In ctrGroupBoxes.Controls.OfType(Of TextBox)
ctrControls.Text = ""
Next
Next
'Get checkboxes and unchecks them
For Each ctrGroupBoxes As Control In Me.Controls.OfType(Of GroupBox)
For Each ctrControls As Control In ctrGroupBoxes.Controls.OfType(Of CheckBox)
DirectCast(ctrControls, CheckBox).Checked = False
Next
Next
I know the inner for loops work as I used it to clear each GroupBox individually for a different button on the form.
Any assistance would be appreciated.

Here's one option that should work regardless of the UI hierarchy:
Dim cntrl = GetNextControl(Me, True)
Do Until cntrl Is Nothing
Dim tb = TryCast(cntrl, TextBox)
If tb IsNot Nothing Then
tb.Clear()
Else
Dim cb = TryCast(cntrl, CheckBox)
If cb IsNot Nothing Then
cb.Checked = False
End If
End If
cntrl = GetNextControl(cntrl, True)
Loop
That will follow the Tab order on the form

A recursive function really isn't that difficult:
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
ClearForm(Me)
End Sub
Private Sub ClearForm(ByVal C As Control)
For Each ctl As Control In C.Controls
If TypeOf ctl Is TextBox Then
ctl.Text = ""
ElseIf TypeOf ctl Is CheckBox Then
DirectCast(ctl, CheckBox).Checked = False
ElseIf ctl.HasChildren Then
ClearForm(ctl)
End If
Next
End Sub
End Class

Related

quick way to disable all textboxfields unlock with edit button

Does Vb.net have a quick way to disable all editable fields (textboxes, checkboxes,...) in a form?
I'm trying to protect data from "accidentally" being overwritten. My user has to click an edit button to "unlock" the fields and make them editable and the user must press the save button to update the database and lock the fields once more.
So far i've only found a manual input to make every textbox and checkbox (about 30 of them in different tabs of the form) readonly values to true and disable them if i click on my edit button.
Any advice on how to do this? can i do a "for each" in a quicker way? how would i formulate the code?
i found a 2007 article with this snippet:
For Each control As Control In Me.Controls
If TypeOf (control) Is TextBox Then
CType(control, TextBox).ReadOnly = True
End If
Next
but i'd need all types of field in one go.
thanks for any advice on this subject. I'm a beginner.
With reference to this question
If you put this in a module called ControlExt.vb:
Imports System.Runtime.CompilerServices
Module ControlExt
<Extension()>
Public Function GetAllChildren(Of T As Control)(parentControl As Control) As IEnumerable(Of T)
Dim controls = parentControl.Controls.Cast(Of Control)
Return controls.SelectMany(Of Control)(Function(ctrl) _
GetAllChildren(Of T)(ctrl)) _
.Concat(controls) _
.Where(Function(ctrl) ctrl.GetType() = GetType(T)) _
.Cast(Of T)
End Function
End Module
Then you could do this in your class:
Class WhateverForm
Private _allTextboxes as List(Of TextBox)
Public Sub New() 'in the constructor
InitializeComponent()
_allTextboxes = Me.GetAllChildren(Of TextBox).ToList()
End Sub
Which means all the textboxes on your form, wherever they are (inside whatever subpanels of subpanels, of tabpages of groupboxes etc), are now in a List.. And you can do this in your edit button click handler:
_allTextboxes.ForEach(Sub(b) b.ReadOnly = False)
And of course, perform the corollary ReadOnly = True in the Save button. You don't have to limit it to textboxes; GetAllChildren can find anything - maybe you want to lock the checkboxes too - have another list of _allCheckboxes, GetAllChildren(Of CheckBox) and in the ForEach set Enabled = etc
I'd point out that ReadOnly and Enabled are slightly different and as a UX pointer if you're going to make stuff greyed out in a UI (or "half greyed out" in the case of ReadOnly), then you should have something explaining why the option is greyed out/how to enable it. It won't be immediately obvious to users that they have to click Enable and if you don't want tech support calls going "I'm clicking in the name box and I can see the cursor flashing but when i type nothing happens!" then give them a nudge with "View mode: To enable editing of this data, click [EDIT]" etc
This will disable every TextBox and every CheckBox that was added directly to a TabPage in TabControl1:
For each tp As TabPage In TabControl1.TabPages
For Each tb In tp.Controls.OfType(Of TextBox)()
tb.Enabled = False
Next
For Each cb In tp.Controls.OfType(Of CheckBox)()
cb.Enabled = False
Next
Next
Try this:
For Each control As Control In Me.Controls
Try
CType(control, TypeOf(control)).ReadOnly = True
Catch
' Do nothing
End Try
Next
Thanks for the GetAllChildren function. Thought I'd share a continuation of it so you can lock all common controls based on a tag.
Public Sub LockControls(ByVal frm_Form As Form,
ByVal bln_Lock As Boolean,
ByVal str_TAG As String)
Dim allTextboxes As List(Of TextBox)
Dim allComboBoxes As List(Of ComboBox)
Dim allDateTimePickers As List(Of DateTimePicker)
Dim allDataGrids As List(Of DataGridView)
Dim allCheckBoxes As List(Of CheckBox)
Dim allListBoxes As List(Of ListBox)
Dim allButtons As List(Of Button)
Dim blnEnable As Boolean
Dim blnReadonly As Boolean
If bln_Lock Then ' we need to lock controls
blnEnable = False
blnReadonly = True
Else
blnEnable = True
blnReadonly = False
End If
allTextboxes = frm_Form.GetAllChildren(Of TextBox).ToList
For Each CTL In allTextboxes
If ContainsTag(CTL.Tag, str_TAG) Then
CTL.ReadOnly = blnReadonly
End If
Next
allComboBoxes = frm_Form.GetAllChildren(Of ComboBox).ToList
For Each CTL In allComboBoxes
If ContainsTag(CTL.Tag, str_TAG) Then
CTL.Enabled = blnEnable
End If
Next
allCheckBoxes = frm_Form.GetAllChildren(Of CheckBox).ToList
For Each CTL In allCheckBoxes
If ContainsTag(CTL.Tag, str_TAG) Then
CTL.Enabled = blnEnable
End If
Next
allButtons = frm_Form.GetAllChildren(Of Button).ToList
For Each CTL In allButtons
If ContainsTag(CTL.Tag, str_TAG) Then
CTL.Enabled = blnEnable
End If
Next
allDateTimePickers = frm_Form.GetAllChildren(Of DateTimePicker).ToList
For Each CTL In allDateTimePickers
If ContainsTag(CTL.Tag, str_TAG) Then
CTL.Enabled = blnEnable
End If
Next
allDataGrids = frm_Form.GetAllChildren(Of DataGridView).ToList
For Each CTL In allDataGrids
If ContainsTag(CTL.Tag, str_TAG) Then
CTL.ReadOnly = blnReadonly
End If
Next
allListBoxes = frm_Form.GetAllChildren(Of ListBox).ToList
For Each CTL In allListBoxes
If ContainsTag(CTL.Tag, str_TAG) Then
CTL.Enabled = blnEnable
End If
Next
End Sub
Private Function ContainsTag(fulltag As String, searchTag As String) As Boolean
Dim found As Boolean
Dim tags As String() = Nz(fulltag, "").Split(New Char() {","c})
For Each tag In tags
If tag = searchTag Then
found = True
End If
Next
Return found
End Function
Public Function Nz(ByVal Value As Object, Optional ByVal DefaultVal As Object = "") As Object
If Value Is Nothing OrElse IsDBNull(Value) Then
Return DefaultVal
Else
Return Value
End If
End Function

Disable textboxes with the corresponding checkboxes in VB.net

Public Class Form1
Dim controlNames() As String = {"Tea", "Cola", "Coffee", "Orange", "Water", "VanillaCone", "VanillaShake", "StrawberryShake", "ChocolateMilkshake", "Fries", "Salad", "Hamburger", "OnionRings", "ChickenSalad", "FishSandwich", "CheeseSandwich", "ChickenSandwich"}
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
For Each ctrl As Control In Me.Panel2.Controls
If TypeOf ctrl Is TextBox Then
ctrl.Enabled = False
End If
Next
End Sub
Private Sub Timer1_Tick(sender As Object, e As EventArgs)
For i = 0 To 16
For Each ctrl As Control In Me.Panel2.Controls
If TypeOf ctrl Is CheckBox Then
If ctrl.Name = "chk" & controlNames(i) Then
If DirectCast(ctrl, CheckBox).CheckState = CheckState.Checked Then
If TypeOf ctrl Is TextBox Then
If ctrl.Name = "txt" & controlNames(i) Then
ctrl.Enabled = True
End If
End If
End If
End If
End If
Next
Next
End Sub
I have a VB.NET assignment and I am attempting to enable textboxes based on whether or not the checkbox with the same name was checked.
This is my code so far and it obviously doesn't work. What I want to do essentially:
All textboxes start as disabled. Then, textboxes only get enabled if the corresponding checkboxes are checked. For example, if chkTea is checked, then it enables txtTea.
I am aware I can copy paste something like "if chkTea = checked then txt.tea = enabled". I do not want to do this as this seems like a poor way to go about this. I want to know if I can do something like my barely readable code shows.
If you're renaming all your controls to something different to the default name with a number, this code should work just fine.
You dont need a timer, it just fires when any of the CheckBoxes have their state changed.
In the example code, I've created a CheckedChanged handler and set it to handle some of the CheckBoxes (You'll want to add all those you want to handle). If you click on any of these CheckBoxes, the handler will fire. The handler then passes which checkbox has been changed to the SyncTextBoxWithCheckBoxState method. This then finds the matching textbox using the FindMatchingCheckBox method and sets the .Enabled state of the Text box to the same as the .Checked state of the CheckBox
Private Sub chkTea_CheckedChanged(sender As Object, e As EventArgs) Handles chkTea.CheckedChanged, chkCoffee.CheckedChanged, chkCola.CheckedChanged, chkOrange.CheckedChanged, chkTea.CheckedChanged, chkVanillaCone.CheckedChanged, chkVanillaCone.CheckedChanged, chkWater.CheckedChanged
SyncTextBoxWithCheckBoxState(CType(sender, CheckBox))
End Sub
Private Sub SyncTextBoxWithCheckBoxState(chkBox As CheckBox)
Dim txtBox As TextBox = FindMatchingTextBox(chkBox)
txtBox.Enabled = chkBox.Checked
End Sub
Private Function FindMatchingTextBox(chkbox As CheckBox) As TextBox
For Each ctrl As Control In Panel2.Controls
If ctrl.GetType Is GetType(TextBox) And ctrl.Name.Contains(chkbox.Name.Substring(3)) Then
Return CType(ctrl, TextBox)
End If
Next
Return Nothing
End Function
EDIT
To have the code target more than one panel, add all the checkboxes you want to detect to the event handler like before, and in the FindMatchingTextBox method, just add another loop around the existing one to loop through each panel. Like so ..
Private Function FindMatchingTextBox(chkbox As CheckBox) As TextBox
'This is the new loop which loops through the two panels. It's
'a bit quick and dirty, but it works
For Each pnl As Panel In New Panel() {Panel2, Panel3}
'In this line note that the reference to Panel2 now refers to pnl
For Each ctrl As Control In pnl.Controls
If ctrl.GetType Is GetType(TextBox) And ctrl.Name.Contains(chkbox.Name.Substring(3)) Then
Return CType(ctrl, TextBox)
End If
Next
'End point of the new loop
Next
Return Nothing
End Function
After you've looped through each checkbox, you are only concerned with that checkbox, so when you find the correct checkbox, you need to then RELOOP back through all the controls on the form checking if they are the corresponding textbox.
Something like the below should work, or at the very least start you off down the right path:
Dim controlNames() As String = {"Tea", "Cola", "Coffee", "Orange", "Water", "VanillaCone", "VanillaShake", "StrawberryShake", "ChocolateMilkshake", "Fries", "Salad", "Hamburger", "OnionRings", "ChickenSalad", "FishSandwich", "CheeseSandwich", "ChickenSandwich"}
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
For Each ctrl As Control In Me.Panel2.Controls
If TypeOf ctrl Is TextBox Then
ctrl.Enabled = False
End If
Next
End Sub
Private Sub Timer1_Tick(sender As Object, e As EventArgs)
For i = 0 To 16
For Each ctrl As Control In Me.Panel2.Controls
If TypeOf ctrl Is CheckBox Then
If ctrl.Name = "chk" & controlNames(i) Then
If DirectCast(ctrl, CheckBox).CheckState = CheckState.Checked Then
For Each ctrl As Control In Me.Panel2.Controls
If TypeOf ctrl Is TextBox Then
If ctrl.Name = "txt" & controlNames(i) Then
ctrl.Enabled = True
End If
End If
Next
End If
End If
End If
Next
Next
End Sub

Single checkbox to check multiple checkboxes in Visual Basic

Hi good people of stackoverflow, I have created a groupBox1 which contains 39 checkboxes which can be checked individually, and I have created a gropuBox2 which contains single check box called "Check All", What I want is when the "Check All" check box is checked all the 39 checkboxes will be selected and when the "Check All" is unchecked all 39 checkboxes will be unchecked also, Can someone please help? Thank you very much.
If all your controls are in the form ( not in groupbox/pannel) you can use the following code
Dim chk As CheckBox
If checkAll.Checked = True Then
For Each ctrl As Control In Me.Controls
If TypeOf ctrl Is CheckBox Then
chk = DirectCast(ctrl, CheckBox)
chk.Checked = True
End If
Next
End If
Updates as per edit and comment:
If you want to find controls inside Groupbox1 means you can do like the following
''' <summary>
''' sets CheckBox.Checked inside a container
''' </summary>
''' <param name="parentControl">the container</param>
''' <param name="chkState">ture or false</param>
''' <remarks>use: checkControls(GroupBox1, True)</remarks>
Public Sub checkControls(ByVal parentControl As Control, chkState As Boolean) '<----Pass the parent control where the checkBoxes belongs
Dim chk As CheckBox = Nothing
For Each ctrl As Control In parentControl.Controls '<-----Change from the above code
If TypeOf ctrl Is CheckBox Then
DirectCast(ctrl, CheckBox).Checked = chkState
End If
Next
End Sub
To check call the function as
checkControls(GroupBox1, True)'<----Since your checkboxes are inside the groupBox1
To uncheck call the function as
checkControls(GroupBox1, False)'<----Since your checkboxes are inside the groupBox1
Here's how I would do it. Filter the controls by type using Enumerable.OfType<T> then iterate the result using Array.ForEach<T>.
Private Sub CheckBoxAll_CheckedChanged(sender As Object, e As EventArgs) Handles CheckAll.CheckedChanged
Array.ForEach(Me.GroupBox1.Controls.OfType(Of CheckBox).ToArray(), Sub(box As CheckBox) box.Checked = Me.CheckAll.Checked)
End Sub
Assuming that there are only 40 checkboxes on the form then this will work
Dim ctrl As Control = Me.GetNextControl(Me, True)
Do Until ctrl Is Nothing
If TypeOf ctrl Is CheckBox Then
DirectCast(ctrl, CheckBox).Checked = True
End If
ctrl = Me.GetNextControl(ctrl, True)
Loop
If there are more than 40 checkboxes then take a look at Neethu Soman's solution.
I've tried the code below and works for me but Bjørn-Roger Kringsjå code works much better:
Private Sub cbxAll_CheckedChanged(sender As Object, e As System.EventArgs) Handles cbxAll.CheckedChanged
If cbxAll.Checked = True Then
cbx01.Checked = True
cbx02.Checked = True
' 3 .. 38
cbx39.Checked = True
Else
cbx01.Checked = False
cbx02.Checked = False
' 3 .. 38
cbx39.Checked = False
End If
End Sub

Clearing many textbox controls in vb.net at once

I am using the following code to clear the
txtint1.Clear()
txtext1.Clear()
txttot1.Clear()
txtint2.Clear()
txtext2.Clear()
txttot2.Clear()
txtint3.Clear()
txtext3.Clear()
txttot3.Clear()
txtint4.Clear()
txtext4.Clear()
txttot4.Clear()
txtint5.Clear()
txtext5.Clear()
txttot5.Clear()
txtint6.Clear()
txtext6.Clear()
txttot7.Clear()
txtint8.Clear()
txtext8.Clear()
txttot8.Clear()
Is there any possibility to clear all the textbox controls at once or with few lines of code?
You can iterate over all controls on the form which are contained in root.Controls and see if it is of type a textbox TypeOf ctrl Is TextBox, then you can clear the text in that control CType(ctrl, TextBox).Text = String.Empty
Well!! You need to use recursion to loop through all controls
Adding the code:
Public Sub ClearTextBox(parent As Control)
For Each child As Control In parent.Controls
ClearTextBox(child)
Next
If TryCast(parent, TextBox) IsNot Nothing Then
TryCast(parent, TextBox).Text = [String].Empty
End If
End Sub
You could put them in an array then loop through the array:
For Each txt In {txtint1, txtext1, txttot1, txtint2, txtext2, txttot2, txtint3, txtext3, txttot3, txtint4, txtext4, txttot4, txtint5, txtext5, txttot5, txtint6, txtext6, txttot7, txtint8, txtext8, txttot8}
txt.Clear()
Next
I tried one of the examples here but this seems to work for me:
Dim a As Control
For Each a In Me.Controls
If TypeOf a Is TextBox Then
a.Text = Nothing
End If
Next
Try this
For Each txt As Control In Me.Controls.OfType(Of TextBox)()
txt.Text = ""
Next
try this one
Dim a As Control
For Each a In Me.Controls
If TypeOf a Is TextBox Then
a.Text = ""
End If
Next
or
Dim a As Control
For Each a In Me.Controls
If TypeOf a Is TextBox Then
a.clear()
End If
Next
if .Clear() is a member of textbox property then use it. i guess .clear() is not a member of textbox properties.
This is my code that I personally use it in my projects ^_^
ClearAll TextBoxes :
For Each TxtBox In Me.Controls.OfType(Of TextBox)
TxtBox.Clear()
Next TxtBox
I had to cast the Control as a TextBox to make this work. Something about the control object not being accessible. There may be a more direct way but I was unable to find one.
I got the idea from https://stackoverflow.com/a/16264904/11242863
Private Sub clearAllTextBoxes()
Dim formControl As Control
Dim txtBox As TextBox
For Each formControl In Me.Controls
If TypeOf formControl Is TextBox Then
txtBox = TryCast(formControl, TextBox)
txtBox.Clear()
End If
Next
End Sub
I hope this helps someone,
Tim R
This Will Reset All controls on Form To Default Value
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
Controls.Clear()
InitializeComponent()
Form1_Load(Me, Nothing)
End Sub
This code is tested and the best code I have used:
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
Controls.Clear()
InitializeComponent()
Form1_Load(Me, Nothing)
End Sub

TextBox Enter Key - Sub Panels within a main Panel

I am having a problem with this scenario (See Title). I have 6 Sub Panels within one big Panel. I have made a TextBox class that inherits from the main Textbox. I am trying to use the KeyPressed Event Handler for handling the Enter key. When a User presses the Enter Key, it moves from one TextBox inside a sub panel into the next sub panel. So far, I have gotten the Enter Key Event handler to work for the panel where the focus is without jumping to the next panel.
Below is subroutine that I am using to control the movements.
The problem is that I am unable to jump from one sub panel to another. Any help would be appreciated!
Protected Shared Sub NextControl(ByVal tControl As Control, ByVal Direction As Boolean)
Dim pControl As Control = tControl.TopLevelControl
tControl = pControl.GetNextControl(tControl, Direction)
If Direction = False Then
Dim tParent As Control
While TypeOf tControl Is UserControl
tParent = tControl.Parent
tControl = pControl.GetNextControl(tControl, Direction)
If tControl.Parent Is tParent Then
Exit While
End If
End While
End If
If tBox_P00.ControlNesting > 0 Then
'Dim i As Integer
pControl = tControl.Parent
For i As Integer = 0 To tBox_P00.ControlNesting - 2
pControl = pControl.Parent
Next
End If
If Not tControl Is Nothing Then
Do Until (tControl.TabStop = True) AndAlso (tControl.Enabled = True) AndAlso (tControl.Visible = True) AndAlso (TypeOf tControl Is Tbx00)
tControl = pControl.GetNextControl(tControl, Direction)
'Last in the Panel
If tControl Is Nothing Then
tBox_P00.Select(0, tBox_P00.TextLength)
Beep()
Exit Sub
End If
Loop
tControl.Focus()
Else
tBox_P00.Select(0, tBox_P00.TextLength)
Beep()
End If
Exit Sub
End Sub
It sounds as though you are complicating things. As HansPassant mentioned you can use GetNextControl to do the work for you:
This code will move the focus to the next textbox on the form (based on tab index order) when enter is pressed:
Private Sub TextBox1_KeyDown(sender As Object, e As System.Windows.Forms.KeyEventArgs) Handles TextBox1.KeyDown
If e.KeyCode = Keys.Enter Then
Dim ctl As Control = CType(sender, Control)
Do
ctl = Me.GetNextControl(ctl, True)
Loop Until TypeOf ctl Is TextBox
ctl.Focus()
End If
End Sub
You could then expand this to handle all textbox KeyDown events.