How do I reference a dynamically named control on a UserControl from the Parent Form? - vb.net

How do I reference a dynamically named control on a UserControl from the Parent Form? (In Winforms).
I have a single parent form but it may load any 1 of around 20 or so UserControls. We will call them ucA, ucB, etc.
Each UserControl has a different number of textboxes, but are named tbA01, tbA02, etc on ucA and tbB01, tbB02, etc on ucB.
How would I reference the value of the textboxes?
I cannot seem to reference the name of the UserControl directly. I know the name of the UserControl as a string, but canot seem to cast it as a control. Likewise with the textboxes on the UserControl. I am sure I can use Control.Find() for the name of the textbox from a simple string. But this doesn't appear to be working, which I assume it will only be looking for controls on ParentForm and not the collection of controls on the UserControl. I assume there would be a method using TryCast or DirectCast and using the Control.Find() in the arguments. But I have not found a solution.
Any help would be appreciated!

Thank you Jimi! Your answer did help me look at a different method in coming up with a solution. I have it working now. Here is what I used:
Dim matches() As Control
matches = Me.Controls.Find(TblName, True)
If matches.Length > 0 AndAlso TypeOf matches(0) Is TextBox Then
Dim tb As TextBox = DirectCast(matches(0), TextBox)
...
Endif

Related

loop through all comboboxes with specific name

is it possible to loop through all comboboxes with specific name. For example I have 25 comboboxes in a groupbox i need to loop through 20 of them (each of this 20 have name special_combo_1,special_combo_2 and etc. but another 5 have another names so i need to leave as they are)and change their width at once or change the text or anything else.
You can use Control.Controls to get all the controls the GroupBox contains.
Then, you should cast each Control object to the ComboBox type by using TryCast(Object, Object).
You can check the prefix with String.StartsWith(String).
For Each Item As Control In GroupBox1.Controls
Dim ComboBoxItem As ComboBox = TryCast(Item, ComboBox)
If ComboBoxItem IsNot Nothing Then
If ComboBoxItem.Name.StartsWith("special_combo_") Then
' Code here
End If
End If
Next
Use the OfType to make a collection of comboboxes from the control collection. No TryCast needed so increase in preformance. Then filter them with the Where clause to drill it down even further. Now you iterate only a small collection of controls.
Dim spComboboxes =
GroupBox1.Controls.OfType(Of Combobox)().
Where(Function(cb) cb.Name.StartsWith("special_combo_")).ToList()
Iterate the comboboxes:
For Each cb In spComboboxes
'do something
Next

Clearing combobox dropdownlists from application

I am working on an assignment that requires a user to answer 20 questions( multiple choice ). I am using the DropDownList property so the user cannot input anything other than A, B, C, or D.
Basically, I have 20 comboboxes and I have a button that clears them, but the code I should obviously be a loop, but I am not sure how to do that.
As of now, my code looks like this:
cboQuestion1.Items.Clear()
cboQuestion2.Items.Clear()
...
cboQuestion20.Items.Clear()
If anyone could shed some light on this, I will be grateful.
All controls reside in the form's Controls collection, so one way would be to iterate that (assumes these CBOs are the only ones you wish to clear):
For Each cbo As ComboBox In Controls.OfType(Of ComboBox)
cbo.Items.Clear
Next
Another way is to store the names of the target controls in a List(of String). Think of this as a shopping list of the controls you wish to track or treat in some special way:
Private myCBONamesList As List(of String)
'...
myCBONamesList.Add("cboQuestion1")
' etc
' add many/all at once:
myCBONamesList.Addrange(New String(){"cboQuestion1", "cboQuestion2" ...etc})
The New String() creates a temp array containing the literal values listed (in {}) and the whole thing is passed to your List to populate it. To use it:
For Each s As String in myCBONamesList
Controls(s).Items.Clear
Next
This method allows you to target certain CBOs and leave others alone.
It may or may not be the best way, but you could add all of your combo boxes to a List and then iterate over the list to clear them all.
Just iterate over the Form's Controls collection.
Here is an example of iterating over the Forms Controls collection with filtering to make sure you don't accidentally clear a non-question ComboBox:
For Each cbo As ComboBox In Me.Controls.OfType(Of ComboBox)
If cbo.Name Like "cboQuestion*" Then
cbo.Items.Clear()
End If
Next
Edit: Or if you're into one-lining things:
For Each cbo As ComboBox In Me.Controls.OfType(Of ComboBox).Where(Function(x) x.Name Like "cboQuestion*")
cbo.Items.Clear()
Next

Programmatically access controls on GroupBoxes that are on multiple Tab Pages

How can you programmatically access controls on Tab Pages?
My code has many properties that I want to allow the user to initially set when the program starts. These properties will be used to define an Excel chart like title name, font colors, font size, chart position and size, X & Y series and many others properties. The program produces many charts each of which have their own set of properties. Each chart has the same set of properties but different values.
My solution using Form1 Designer:
I Placed the TabControl1 control from the VS 2010 toolbox on Form1.
I created 19 TabPages on TabControl1
On each TabPage I created multiple GroupBoxes for organization.
Finally, I placed multiple controls like RadioButtons, TextBoxes, and Spinners in each of the GroupBoxes.
All of the above was done at design time.
Bad Example:
Dim TC1 As TabControl = TabControl1.TabPages.Item(1)
This is a bad example but I’m thinking I need to do something like this, i.e. before I can reach the actual user inputs via the RadioButtons, TextBoxes, or Spinners child controls I need to tell the complier the name of the TabControl1 and each TabPage contained in it. I’m not sure about each of the GroupBoxes that contain groups of RadioButtons and etc.
My Question: How do you programmatically access controls located on multiple GropBoxes located on each of the Tab Pages? I want to retrieve all the user input properties values on each of many TabPages and apply them when I create the Excel Charts.
A TabControl is just a fancy way to organize controls on the same form. The point is that they are on the same form! You probably know that you use Me to access the current form, then .ControlName to access the control. Consider a TabControl with two tabs and on each tab there is a TextBox. These TextBoxes are on the same form, so you still need to use
Me.TextBox1.Text = "Text 1" ' the same as TextBox1.Text = "Text 1", but I like to be explicit
Me.TextBox2.Text = "Text 2"
This you already knew, as your problem stemmed from this behavior. However, there are some tricks to help you. Consider a TabControl with two tabs, and on page 1 there is a control named tc1TextBox1 and on page 2 tc2TextBox1. I'm using the prefix to distinguish between the pages. An additional TextBox on page 1 would be named tc1TextBox2 etc., then say you wanted CheckBoxes, you could have tc1CheckBox1 and tc1CheckBox2 etc. The way I would access them is with LINQ
Define an extension method in a module
Imports System.Runtime.CompilerServices
Public Module ExtensionMethods
<Extension()> _
Public Function ChildControls(Of T As Control)(ByVal parent As Control) As List(Of T)
Dim result As New List(Of Control)
For Each ctrl As Control In parent.Controls
If TypeOf ctrl Is T Then result.Add(ctrl)
result.AddRange(ctrl.ChildControls(Of T)())
Next
Return result.ToArray().Select(Of T)(Function(arg1) CType(arg1, T)).ToList()
End Function
End Module
This method returns you all the Controls inside parent, and all Controls inside those, and so on, recursively. It also gives you an IEnumerable List(Of Control) in contrast to Control.Controls() which is not IEnumerable and only returns controls in the control, not in its containers.
Using LINQ, you can filter the results of ChildControls by Type or Name. For instance, the code
Dim textBoxes = Me.ChildControls(Of TextBox)()
returns all the TextBoxes in Me. Let's take it a step further:
Dim textBoxes = Me.ChildControls(Of TextBox)().Where(Function(tb) tb.Name.StartsWith("tc1"))
returns all the TextBoxes with the prefix "tc1". So you see you can set up the controls on your form to better group them at runtime. Here's an idea specific for Excel sheets
Dim xlBook As Excel.Workbook
For i As Integer = 1 To 20
Dim nameString = "txtSheetName" & i.ToString() ' TextBoxes named txtSheetName1, txtSheetName2, etc.
xlBook.Sheets(i).Name = Me.ChildControls(Of TextBox)().Where(Function(tb) tb.Name = nameString).First().Text
Dim enabledString = "chkEnabled" & i.ToString() ' CheckBoxes named chkEnabled1, chkEnabled2, etc.
xlBook.Sheets(i).Enabled = Me.ChildControls(Of CheckBox)().Where(Function(tb) tb.Name = enabledString).First().Checked
'etc.
Next
which will loop over your tab control indices, and set properties for each corresponding excel sheet. This code should give you a good idea of a direction you can take.

VB.NET For each exception on custom controls

in VB.NET i have 2 custom controls, one is a TextBox and second one is a ComboBox.
These have custom values like Bool _IsHidden and are added on runtime to a form.
Now, at some point in the code I want to check if the _IsHidden is set to True or False and display that information. Since the user can edit this values when creating the control these are not set on creation.
So what I tried is:
(all of this is on MDI Forms)
For Each frm as CustomForm in Main.MdiChildren
If frm.MyName = calledBy Then 'this part is just to know which form called the form to create the object
For Each cntrl as CustomTextBox in frm.Controls
'DO Something
Next
End if
Next
Now.. if the first control is a custom ComboBox it thorws an error since it sees that it does not match the custom TextBox control..
how do i get around this? By my understanding it should just go through all of the controls on the said form and just check those who match CustomTextBox control ?
Thank you
For Each x As T In collection does not filter your collection items to those of type T. It tries to convert every item in collection to T and throws an exception if that fails.
Thus, you have the following options:
Do the check yourself, for example, using the code provided by RB.
Alternatively, you could filter your list first, and then loop through the items. Here, LINQ can help:
For Each cntrl In frm.Controls.OfType(Of CustomTextBox)()
... ' Do this for all CustomTextBoxes
Next
For Each cntrl In frm.Controls.OfType(Of CustomComboBox)()
... ' Do this for all CustomComboBoxes
Next
You don't need the As CustomTextBox clause here, since frm.Controls.OfType(Of CustomTextBox)() returns an IEnumerable(Of CustomTextBox), so For Each can infer by itself that cntrl must be of type CustomTextBox.
By my understanding it should just go through all of the controls on
the said form and just check those who match CustomTextBox control ?
That's not correct I'm afraid. You'll need to implement that check yourself, e.g:
For Each cntrl as object in frm.Controls
If TypeOf cntrl Is CustomTextBox Then
With CType(cntrl, CustomTextBox)
.DoSomethingWithControl()
.DoSomethingElseWithControl()
End With
End If
Next

how to clear all tools in the vb.net from

i have used many of the controls in vb.net forms, including a textbox and combobox, but I want to clear all my text boxes at once, while not typing textbox1.clear() for each one.
Is there any other way to clear all my textboxes?
If I understand you question right, you should be able to loop through all the controls on your form and check to see what Control type they are. Based on their type, either set the textbox Text property to String.Empty, or your ComboBox to the index of a blank ListItem (presumably item zero).
Something like:
For Each ctrl As Control In Me.Controls
If TypeOf ctrl Is TextBox Then
CType(ctrl, TextBox).Text = String.Empty
Else
' do something similar for your ComboBox
End If
Next
You can parse through each control on your form and test what type of control that is and handle each type separately, but it is easier to simply set each control manually.
Consider writing a ClearForm routine that does all of this, that way all you have to do is call the method.