Adding a letter to the name of an object - vb.net

I have a series of pairs text fields that are pragmatically added, one is called 0_1 and the other is called 0_1w. I am wanting todo something to 0_1w when an event happens (keypress) to 0_1, and the same with 0_2, 0_3 etc...
Is it possible to just grab the sender for the keypress event and append the letter w to the end of it or is there any simple way I can do what I need with the w text field from within the other text field.
Thanks

Each control has a Name property, so if you cast the sender to Control, you'll be able to get that name string. You can then append "w" to it and look for another control with that name. You can look up controls by name using the Controls collection on the form.
Dim senderName As String = DirectCast(sender, Control).Name
Dim pairedName As String = senderName & "w"
Dim paired As Control = Me.Controls(pairedName)
However, the form's Controls collection only contains the controls that are directly added to it. If the sender is inside a container control, such as a Panel, only that panel control will be included in the form's Controls collection. In a case like that, you'd need to look at the panel's Controls collection. Therefore, since the two paired controls are probably inside the same container control, it would be safer to do this:
Dim paired As Control = DirectCast(sender, Control).Parent.Controls(pairedName)

Related

Is there a way to update a TextBox when is not visible?

I have a TextBox nested inside a TabControl.
Form->TabControl1->TabPage1->TabControl2->TabpPage2->GroupBox->TextBox
When the TabPage1, TabPage2 is selected, so the TextBox is visible to the user all the TextBoxEvents works OK, but when the user selects another TabPage it doesn't work.
I have a timer that send data periodically to know if an external device is present on a specific virtual COM port.
When the external device answer I put that data in that TextBox and set a global flag(boolean) to let the rest of the program that a device is present.
I'm processing the received data on a Private Sub and changing that TextBox with a Lambda expression like this
Me.Invoke(Sub()
Me.VersionFirmwareTxt.Text = RespX.Substring(5)
End Sub)
You can access the TextBox by name from anywhere whether it is visible or not, via casting (CType), and update its text value using the syntax:
'(from within the same Form, e.g., Form1)
CType(TabControl1.TabPages(1).Controls("VersionFirmwareTxt"), TextBox).Text = RespX.Substring(5)
'(from a different Form)
CType(Form1.TabControl1.TabPages(1).Controls("VersionFirmwareTxt"), TextBox).Text = RespX.Substring(5)
If you dynamically added the TextBox to the controls of the parent (TabPage), you will know exactly where the TextBox is located, since you would have already used, e.g.:
TabControl1.TabPages(1).Controls.Add(VersionFirmwareTxt)
Whereas if you manually added the TextBox to the TabPage, you also know the parent control.

How do I reference a dynamically named control on a UserControl from the Parent Form?

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

Combobox not updating bindtable fields in VB

I have a combobox that is of type dropdown, i.e. allows user to either select something from the list or to type in a new value. Based on this combo value, other values are selected in the form automatically as they are databound.
Customer_ID is the field that needs to be picked or typed in, and based on it Customer first name and second name are updated in the form automatically. This works fine if I pick some value from dropdown, lets say Customer Id = 1111.
Now in place of picking, if i type in this value and press tab, no udpate happens on the Name fields. Please suggest what am I missing here.
I think the best you are going to do with the standard ComboBox is to handle the Leave event, or possibly the TextChanged event. I did some experimenting and typing in a value does not add to the list, it just changes the Text property. It doesn't even change the value of the item you typed over. And, it doesn't fire SelectedItem or IndexChanged events.
So if you handle the Leave event, you have a place to do your lookup when someone tabs off the ComboBox. But the item won't get added to the list.
If you need functionality not provided in the default control, you could redesign your UI with perhaps a TextBox and Button that add an item. Or, you could look for third party implementations of ComboBox controls that would have more functionality.
Private Sub ComboBox1_Leave(sender As Object, e As EventArgs) Handles ComboBox1.Leave
Dim theCB As ComboBox = DirectCast(sender, ComboBox)
DoLookup(theCB.Text)
End Sub

VB.NET - Is there a way to take a string name of a panel and find the panel associated?

I'm working in VB.NET and I'm rather new. I'm doing a search for each button on a panel with:
For Each _x_ As Control In _y_.Controls
I have the y as a string name, is there a way to convert this string to the actual panel or controls group that is associated so I don't have to code for each individually?
Is there an easier way to do this?
i.e.
private function return_button(ByVal y As integer)
Dim z As String = R_ + ToString(y)
(z is now the panel name I am using, but it's a string not the panel itself)
All controls are referenced in their parent's Controls collection. So, if the panel you are looking for is a child of your form, you can look for it in your form's Controls collection. The Controls collection is indexed by the controls' names, so you can retrieve them easily by name, like this:
Dim z As String = ...
Dim p As Panel = DirectCast(Me.Controls(z), Panel)
I figured a solution to this issue. For whatever reason it wouldn't allow me to cast the variables to an instantiated value, it always remained null/nothing. So instead I wrote:
Dim p As String = "<String related to the panel I am looking for>"
Dim panel() = Me.Controls.Find(p, true)
Now I can prove the panels are equal by calling:
MsgBox(panel(0).GetHashCode = <panel name>.GetHashCode)
and was now certain they were the same object so I did a the for loop and it worked with the panel. Now I can loop for the entire TabPage and find all the Panels on this tab. That will make my code far more streamlined than it was prior. Thank you for setting me on the right path, Steven.

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.