Iterate on available control and check if this are enabled - vb.net

I want iterate on GroupBox controls and check if the CheckBox are Checked or not. Actually I'm stuck on this:
For Each c In User.GroupBox3.Controls
If c.GetType.Name = "CheckBox" Then
If c.Checked = True ..?
End If
Next
How you can see I can't access to .Checked property, someone know how can I figure out?

Its about Types. CheckBox is a Type, which inherits from Control which is another Type. Since a ControlsCollection holds the items as Control, you have to cast to the specific Type in order to access the more specific properties and methods:
Long Form:
For Each c As Control In TabPage1.Controls
' check if it is the Type we are looking for
If TypeOf c Is CheckBox Then
' convert to desired type, do something
CType(c, CheckBox).Checked = True
End If
Next
CType converts/casts from Control to CheckBox.
Short Form:
For Each c As CheckBox In TabPage1.Controls.OfType(Of CheckBox)()
c.Checked = True
Next
This version filters to a given Type so the cast isnt needed.

Related

How can I get the checkbox.checked event to fire when I pass it as a parameter in vb.net?

I have programmed a long time but I’m relatively new to vb.net. And I’ve avoided subroutines and functions in which I passed parameters because I always get stuck. I’m trying to write a subroutine to pass information that will fill a TextBox or a checkbox with either the value from a table or clear the field or set to false. The first code below is an example of what I’ve been doing and this works. I trying to write a subroutine to pass 1.the name of the textbox or checkbox control on my form,2.the data row value, and 3.the column name in the table. The problem is when I passed a checkbox I can’t get the checked event to show on my control(CoreCol) that I passed. It knows it’s a checkbox and it will set the text of the checkbox too true or false but it won’t change the box checked.
This is an example of the old way that works. For a TextBox and a checkbox
' A Machine
If Not IsDBNull(r("A Machine")) Or Not IsNothing(r("A Machine")) Then
TbXMachA.Text = r("A Machine")
Else
TbXMachA.Text = ""
End If
If Not IsDBNull(r("A CO2 Box?")) Or Not IsNothing(r("A CO2 Box?")) Then
CkbxCO2BoxA.Checked = r("A CO2 Box?")
Else
CkbxCO2BoxA.Checked = False
End If
This works
LoadData2TextBox(Me. TbXMachA, r, "A Machine ")
This doesn’t
LoadData2TextBox(Me.CkbxCO2BoxA, r, "A CO2 Box?")
this is the sub routine I'm writing
Private Sub LoadData2TextBox(ByRef CoreCol As Control, CoreRow As DataRow, BoxStage As String)
If Not IsDBNull(CoreRow(BoxStage)) Then
If TypeOf CoreCol Is TextBox Then
CoreCol.Text = CoreRow(BoxStage)
End If
If TypeOf CoreCol Is CheckBox Then
CoreCol.??? = CoreRow(BoxStage)
End If
Else
CoreCol.Text = ""
End If
You know that CoreCol is a CheckBox so you can cast it as one then use it as a CheckBox.
If TypeOf CoreCol Is CheckBox Then
Dim myCheckBox = DirectCast(CoreCol, CheckBox)
myCheckBox.Checked = DirectCast(CoreRow(BoxStage), Boolean)
End If
Another cast in getting the boolean value out of CoreRow(BoxStage). The above code assumes this will work, but I am not sure what is in CoreRow(BoxStage). You may need to add some logic based on the value depending on what it is. For example:
myCheckBox.Checked = CoreRow(BoxStage) = "somevalue"

How to determine the Object Type from the field name in a form?

I am trying to generalize this Sub. The sub works, without the test for the checkbox, for text fields. A checkbox has no .BackStyle nor a .ForeColor property.
I tried the code below:
Private Sub EnableEdit(strFieldname As String, Optional bUseRed As Boolean = False)
Me.Controls(strFieldname).Enabled = True
Me.Controls(strFieldname).Locked = False
If Not(TypeOf (Me.Controls(strFieldname)) Is CheckBox) Then
Me.Controls(strFieldname).BackStyle = 1
If bUseRed Then
Me.Controls(strFieldname).ForeColor = vbRed
Else
Me.Controls(strFieldname).ForeColor = vbBlack
End If
End If
End Sub
However
If Not(TypeOf (Me.Controls(strFieldname)) Is CheckBox) Then
is not syntactically correct. TypeOf expects an object and Me.Controls(strFieldname) is the control itself.
I tried alternative ways for Me.Controls(strFieldname).
https://learn.microsoft.com/en-us/dotnet/visual-basic/programming-guide/language-features/early-late-binding/determining-object-type
If you're using standard Access controls, the easiest way is just to access the ControlType property
If Not Me.Controls(strFieldname).ControlType = acCheckbox Then
For special controls, TypeOf can be beneficial. You need to specify the class, which is likely Access.Checkbox (msforms.Checkbox can be used in Access as well but is very unusual).
If Not TypeOf Me.Controls(strFieldname) Is Access.Checkbox Then
The main source of your error, by the way, is the excessive use of parentheses. If you surround an object with parentheses, you get its default property:
Me.Controls("MyCheckbox") 'A checkbox
(Me.Controls("MyCheckbox")) 'The value of a checkbox
The line If Not(TypeOf (Me.Controls(strFieldname)) Is CheckBox) Then has a problem:
The correct syntax would be:
If Not TypeOf Me.Controls(strFieldname) Is CheckBox Then

Unchecking all RadioButtons in a For Each Control loop

I've got 7 RadioButtons on my form, 5 in one group, 2 in another. When they were in GroupBoxes, checking one of the RadioButtons didn't uncheck the other ones in the same GroupBox, for some reason - I think because the AutoCheck value was set to False, which it had to be because otherwise when the form loaded, one of the RadioButtons would be checked by default, and I don't want this to happen.
So, to uncheck the other RadioButtons within the same GroupBox, I'm trying to write a subroutine which is called, after setting the value to True in the RadioButton_Click event.
For Each c As Control In Me.Controls
If TypeOf c Is RadioButton Then
If c.Name <> "rbtnAllSuppliers" AndAlso c.Name <> "rbtnIndividual" Then
If c.Name <> rbtn.Name Then
For Each rbt As RadioButton In Me.Controls
If rbt.Name = c.Name Then
rbt.Checked = False
End If
Next
End If
End If
End If
Next
This code moreorless works. For each control on the form, if it's a RadioButton which isn't called rbtnAllSuppliers or rbtnIndividual (The 2 seperate RadioButtons, and it's not the RadioButton that is being set to True, then set it to False.
The issue being, it is counting the 2 Labels as RadioButtons, or at least casting them to be so, so it errors when trying to set a ``Checkedvalue of theLabel`.
I then tried something similar
For Each c As Control In Me.Controls
If c.GetType Is GetType(RadioButton) Then
If c.Name <> "rbtnAllSuppliers" AndAlso c.Name <> "rbtnIndividual" Then
If c.Name <> rbtn.Name Then
AddHandler DirectCast(c, RadioButton).Checked, AddressOf c.
End If
End If
End If
Next
But I'm not sure what I would put for the AddressOf code? What would go in here as the delegate? If I put AddressOf currentSubroutine(), surely an infinite loop will be created?
Is there a way to uncheck all RadioButtons using a similar method that I'm not aware of?
What's the best way to go about achieving this?
By using Me.Controls.OfType(Of RadioButton) you can avoid having to check the type inside your loop, and will ensure that every control is a RadioButton
To add to the suggested approach, you can also specify which group you want to loop through the controls.
For Each RadioButtonItem In TargetGroupBox.Controls.OfType(Of Radiobutton)
RadioButtonItem.Checked = False
Next

Loop - set Textboxes to ReadOnly in all Groupboxes

I have groupboxes that contain textboxes and I want to set all of them to ReadOnly=True. Here is what I tried (doesn't work):
EDIT (I forgot about Split container):
For Each SplitCon As Control In Me.Controls
If TypeOf SplitCon Is SplitContainer Then
For Each GBox As Control In SplitCon.Controls
If TypeOf GBox Is GroupBox Then
For Each ctrl As Control In GBox.Controls
If TypeOf (ctrl) Is TextBox Then
CType(ctrl, TextBox).ReadOnly = True
End If
Next
End If
Next
End If
Next
You can simplify things a great deal. Rather than looking thru all sorts of Control collections, create an array to act as a ToDo list. Then you can get rid of all the TypeOf and CType in the loop used.
' the ToDo list
Dim GrpBoxes = New GroupBox() {Groupbox1, Groupbox2,
Groupbox3, Groupbox4}
For Each grp In GrpBoxes
For Each tb As TextBox In grp.Controls.OfType(Of TextBox)()
tb.ReadOnly = True
Next
Next
Your code no longer depends on the form layout of the moment. The only thing you have to remember is to add any new GroupBox items to your list. You can also declare the array once ever for the whole form if you prefer (or even in the For Each statement)
Rather than working with Control objects, Controls.OfType(Of T) filters the collection and returns an object variable of that type, so there is no need to cast it or skip over controls you are not interested in. You can also tack on a Where method to further refine the list to include only do those with a certain name or Tag.

Clearing check boxes in VB.NET

I'm doing an assignment for Uni and in my VB.NET form I have some checkboxes, I'm trying to loop through and clear them (I have a button which will clear the form)
My problem is that there seems to be no property I can use to set the state of a checkbox when not explicitly telling VB which checkbox I want to use. for example, I can go
WineCheckBox.Checked = False
That will check the box, but I wand to DRY the code up a bit and not have to repeat this for each check box I have, this is what I was trying to do:
If TypeOf element Is CheckBox Then
element.Checked = False
End If
I've tried using element.CheckState and element.Checked and both times I get "Checked (or CheckState) is not a member of System.Windows.Forms.Control"
I've looked through all the attributes that I can find for this and none of them seem of use to me...
Am I missing something? or is this just not possible to do
Thanks
EDIT:
this is the whole block of code:
'clear the controls
For Each element As Control In Me.Controls
If TypeOf element Is TextBox Then
element.Text = ""
End If
If TypeOf element Is CheckBox Then
element.Checked = False
End If
Next
What type have you declared element as? If its just a Control then this is a base type for CheckBox that doesn't have the checked property. Maybe try:
If TypeOf element Is CheckBox Then
DirectCast(element,CheckBox).checked = False
End If
How about:
For Each element As Control In Me.Controls
If TypeOf element Is TextBox Then
element.Text = ""
End If
If TypeOf element Is CheckBox Then
Dim chk As CheckBox = CType(element, CheckBox)
chk.Checked = False
End If
Next