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

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

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"

Change Label Text with Controls in VB

I'm trying to change a Label Text with Controls command, using this line
Controls("C_" & 0).Text = "Conta:"
But I get this error
"System.NullReferenceException"
If I delete this label and change it for a textbox (with same name "C_0"), it works! But I need to do this with a Label not a textbox...
This is because you do not have a control named C_0. I would suggest using ControlCollection.Find to get your control and then use a conditional If statement to check if the returned control exists:
Dim desiredControls() As Control = Me.Controls.Find("C_" & 0, True)
If desiredControls.Count = 0 Then
'No controls named C_0 found
ElseIf desiredControls.Count > 1 Then
'Multiple controls named C_0 found
Else
desiredControls(0).Text = "Conta:"
End If
Or if you simply wanted a one-liner then you would use:
Me.Controls.Find("C_" & 0, True).First().Text = "Conta:"
However, I would highly recommend that you use the conditional If statements so that you an exception isn't thrown if 0 controls are found.
Ok, I find the problem... This command wasn't working because it was inside a GroupBox.
Then the right code is
Me.Controls("GroupBox1").Controls("C_" & 0).Text = "123"
Thanks for everyone help!
Your problem is control.Controls only returns the controls directly inside the control. So you can use these extension methods. Put this in a Module:
<Extension>
Public Function ChildControls(parent As Control) As IEnumerable(Of Control)
Return ChildControls(Of Control)(parent)
End Function
<Extension>
Public Function ChildControls(Of TControl As Control)(parent As Control) As IEnumerable(Of TControl)
Dim result As New List(Of TControl)
For Each ctrl As Control In parent.Controls
If TypeOf ctrl Is TControl Then result.Add(CType(ctrl, TControl))
result.AddRange(ctrl.ChildControls(Of TControl)())
Next
Return result
End Function
Here is how you would use it:
' general option to return all controls, filter on name
Me.ChildControls().Single(Function(c) c.Name = "C_" & 0)).Text = "Conta:"
' generic option to return only Labels, filter on name
Me.ChildControls(Of Label)().Single(Function(c) c.Name = "C_" & 0)).Text = "Conta:"
This will work whether the Label is in the GroupBox or not, and if you move it to a different GroupBox, Panel, or back to the Form, without needing to change your code.

Iterate on available control and check if this are enabled

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.

refer to name with variable in visual studio 2010 vb

I'm trying to assign text from "comp" in the form "home" to a textbox with the name "d1" in the form "home".
but this needs to be done with a counter in the form "home".
The code is in a module.
What I've tried=
home.controls("d" & home.counter).text = home.comp.text
I keep getting an error:
use the new keyword to create an object instance ==> the textbox exists in the form
check to determine if the object is null before calling the method ==> the textbox is empty
get general help for this exception
You could use Controls.Find:
Dim controls = home.Controls.Find("d" & home.counter, True)
If controls.Length > 0 Then
Dim txt = TryCast(controls(0), TextBoxBase)
If txt IsNot Nothing Then
txt.Text = home.comp.text
End If
End If
However, normally i would not use this approach since it's error-prone. Why don't you provide a public property in the Home-form that you can access? This property would get/set the TextBox' Text.
For example:
Public Property HomeCompText As String
Get
Return txtHomeComp.Text
End Get
Set(value As String)
txtHomeComp.Text = value
End Set
End Property
Now you can use this clear, safe and maintainable code:
home.HomeCompText = home.comp.text
You could even change the underlying control.

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