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

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.

Related

Cannot grab list box using Visual Basic in a Word document

My goal for what I am trying to do overall is have one box on a document that holds a database type and when someone select that database type the document will hide/show certain sections.
Well my issue right now is that I cannot seem to grab the the list box ContentControl I created.
I have a listbox ContentControl with a tag boxDB.
Currently this is all that I can get
Sub ListBox_AfterUpdate()
Dim box
Set box = ActiveDocument.SelectContentControlsByTag("boxDB")
End Sub
I have tried several things with box to try and get it to have data. My first assumption was that since it is a collection I would just find the first item by using the first index of the items..but it always says that there is no item at that index.
Is there another method I should be using to grab the value that was set?
In order to access the control and it's features by tag, read the reference documentation for SelectContentControlsByTag. This shows that the returned object is a collection of controls that match the tag, so clearly you might have several controls with the same tag string.
You will help yourself quite a lot by always using Option Explicit in all your code and by specifically declaring each variable with a type. That way you can use the Intellisense feature of the VBA Editor to reveal what methods and properties are available as you write your code.
Assuming that your ContentControl is already established with the tag (and that you only have one control with that tag
Option Explicit
Sub SetupListbox()
Dim theControls As ContentControls
Dim box As ContentControl
Set theControls = ThisDocument.SelectContentControlsByTag("boxDB")
Set box = theControls.Item(1)
box.DropdownListEntries.Add "Red"
box.DropdownListEntries.Add "Green"
box.DropdownListEntries.Add "Blue"
box.DropdownListEntries.Add "Yellow"
box.DropdownListEntries.Add "Orange"
End Sub
Sub GetSelectedItem()
Dim theControls As ContentControls
Dim box As ContentControl
Set theControls = ThisDocument.SelectContentControlsByTag("boxDB")
Set box = theControls.Item(1)
Debug.Print box.Range.Text
End Sub

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

Adding a letter to the name of an object

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)

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.

How to add a control after another dynamically?

What i am looking for is how to add another control(say a textbox directly under another textbox) that is added through code rather than the designer. I can get it to work using the .height property of the control then adding another 10-20 to it
dim space as integer
space += textbox1.height + 10
however, is there a way to do this on the location rather than the height? In this case, if I want to add a textbox at the very end of the frame or groupbox without having to add additional in between. Since the location takes two parameters(x,y), is it possible to place controls based on another controls location?
Does this help? (not clear what you are after, but yes, you can set the Location or Size all at once):
Dim thisTB as new TextBox
thisTB.Location = new Point(xSpot, ySpot)
thisTB.Size = otherTB.Size
Me.Controls.Add(thisTB)