Refer to forms controls using variable - vb.net

I've seen many threads on this, but I'm pretty much lost.
For the example below, I have 3 ComboBoxes (cbx_example0, cbx_example1, cbx_example2) located on three TabPages (index 0, 1, 2), respectively. I'd like set the value of the variable myVariable based on the ComboBox on the selected TabPage.
However, I can't seem to figure out how to refer to the ComboBox using a variable. It seems like it should be straightforward, but I guess not. No matter what I do, I get a NullReferenceException.
Function to get TabPage Index number (returns 0 for this example)
Function getTabIndex()
Dim currentTabIndex As Int32 = frm_Main.TabControl1.SelectedIndex
Return currentTabIndex
End Function
Attempt 1 to refer to ComboBox with variable
Dim myVariable As String
Dim i As Integer = getTabIndex
myVariable = frm_Main.Controls("cbx_example" & i).Text
Attempt 2 to refer to ComboBox with variable
Dim cbx_example0 As New ComboBox
Dim i As Integer = getTabIndex()
Dim name As String = "cbx_example" & i.ToString
cbx_example = frm_Main.Controls.Item(name)
myVariable = cbx_example.Text

Your problem is that you think that your cbo is located on the form, while in reality it is on the tabpage. Instead of
cbx_example = frm_Main.Controls.Item(name)
use (for example)
cbx_example = frm_Main.TabPage1.Controls.Item(name)
Keep in mind that your combo is probably not on tab itself but on the tabpage
On another note, I see no need for getTabIndex(). And another way to get any control within hierarchy of your form is to use
form.Controls.Find(key, searchAllChildren)

Related

Visual Basic Iterative enabling of Textbox's

Si I'm working on an assignment where I have 10 RadioButtons indicating how many contesters I have, and depending on what I pick between 1 to 10, I need that many of my corresponding TextBoxes to be enabled so I could fill it with names!
Is there a way for me to make a For loop between 1 and the number I picked from the RadioButton and say something like
For i = 0 to Size
{
TextBox&i.Enabled = True
}
Since my TextBoxs are called TextBox1 to TextBox10
I know you can add strings together using &, but how can I do that for an object name?
As of right now I literally have the dumbest way of doing it, which is a click event inside each RadioButton that manually enables the correct number of TextBoxes...
Thank you in advance!
You can iterate over all controls like this:
For Each ctr In Me.Controls
Dim indx As String = ctr.Name
If TypeOf (ctr) Is Textbox Then
' Now compare the name with TextBox&i and do smth
End If
Next
It's not possible to just concatenate a string and use it as an object variable reference like that, but you can search the form's controls by their name property (which is a string) and do it that way. Here's an example:
Private Sub EnableTextBoxes(ByVal Size As Integer)
For i As Integer = 1 To Size
Dim matches() As Control = Me.Controls.Find("Textbox" & i.ToString, True)
If matches IsNot Nothing AndAlso matches.Length = 1 Then matches(0).Enabled = True
Next
End Sub

Adding stuff to listview from textbox

id like to know how to take one of my text boxs or strings and put it in a listview.. well not really let me show u wants going on.
i have a 2 text box with the following stuff
TextBox1
cat123
hatcat
quanwall
samiam12
TextBox2
John
will
sam
dan
i want to take TextBox1's text and put it in one of the columns in the ListView. for example. ListView has 2 columns saying usernames and realnames, and TextBox1 is the usernames and TextBox2 is the realnames. So i want to take each line in TextBox1 to match up with the RealNames(TextBox2) all in ListView.
iv bin using the
Dim Q As New ListViewItem
Q.Text = Host
Q.SubItems.Add(User)
Q.SubItems.Add(Pass)
ListView1.Items.Add(Q)
to add the strings to the listview
I need this information ASAP, Thx u <3
Try this (To listview1 put your listview name)
Dim i As Integer = 0
For Each l In TextBox1.Lines
ListView1.Items.Add(l)
ListView1.Items(ListView1.Items.Count - 1).SubItems.Add(TextBox2.Lines(i))
i += 1
Next
i = 0
While the straightforward answer to your question is rather simple, your posted question raises issues. You are using Listbox and Listview interchangeably, yet they are two different controls. Moreover you seem to suggest your Textbox holds multiple values where the intention of a Textbox is to hold one distinct value or string of text.
As these controls are Windows Forms controls, your use of "Dim Q As New ListviewItem" may not be neccessary.
I would suggest reading up more on the controls you want to use, how they are used and in what context.
The simple straightforward answer to your question could be:
listBox1.Items.Add(textBox1.Text)
For reference: How to: Add and Remove Items with the Windows Forms ListView Control
I'm assuming your user names are stored in TextBox1 and your real names are stored in TextBox2
Public Sub AddListViewItemsFromTextboxes()
Dim Host As String = "SomeHost" 'you mentioned a host in the code snippet in your question, not sure where this comes from
Dim TextBox1String As String = TextBox1.Text
Dim TextBox2String As String = TextBox2.Text
Dim TextBox1Lines() As String = TextBox1String.Split(vbNewLine)
Dim TextBox2Lines() As String = TextBox2String.Split(vbNewLine)
If(TextBox1Lines.Count <> TextBox2Lines.Count)
'possible error handling here
MsgBox("Each user must have both a real name and a username.")
Exit Sub
End If
For NameIndex As Integer = 0 to (TextBox1Lines.Count - 1)
Dim UserName As String = TextBox1Lines(NameIndex)
Dim RealName As String = TextBox2Lines(NameIndex)
Dim Item As New ListViewItem
Item.Text = Host
Dim UserNameSubItem As New ListViewitem.ListViewSubItem
UserNameSubItem.Text = UserName
Item.SubItems.Add(UserNameSubItem)
Dim RealNameSubItem As New ListViewItem.ListViewSubItem
RealNameSubItem.Text = RealName
Item.SubItems.Add(RealNameSubItem)
ListView1.Items.Add(Item)
Next
End Sub
Example GUI:
http://i.stack.imgur.com/du95F.png
EDIT: Added third column

Storing datagridview name in a variable

I am working on user rights. I want to load the grid items checked using following code.
Dim l As Integer = 0, vrGridName As New DataGridView, vrGridItemIndex As Integer
taSaveTemplates.Connection.ConnectionString += ";password=" & vrSAPWD
Me.taSaveTemplates.Fill(Me.DsSaveTemplates.tblTemplates, lstTemplateID.Text)
'Load Grids according to data saved
Do While DsSaveTemplates.tblTemplates.Rows.Count > l
vrGridName.Name = DsSaveTemplates.tblTemplates.Rows(l).Item("GridName")
vrGridItemIndex = DsSaveTemplates.tblTemplates.Rows(l).Item("GridItemIndex")
vrGridName.Item(0, vrGridItemIndex).Value = True
l = l + 1
Loop
vrGridName stores the name of grid selected from DB and vrGridItemIndex stores the item that needs to be checked.
The problem is, when I run the code, it says Index is our of range.
I have checked, the vrGridName does not store the name of grid but stores
System.windows.datagridview
Please advise.
Thanks
Your code is treating a control reference as if it were a name (string variable), so you get the Type name (System.windows.datagridview) rather than the name of the control. Since the template DGV happarently has the name, use it:
Dim myGridName As String ' name is a String, not DGV
Dim myGridItemIndex As Integer
Dim myDGV As DataGridView ' no NEW - not creating a new one
' just a reference var
'...
' this is now a For/Each loop
For Each row As DataGridViewRow in DsSaveTemplates.tblTemplates.Rows
myGridName = row.Cell("GridName")
myGridItemIndex = row.Cell("GridItemIndex")
' assuming this code is in a Form:
' get a reference to the control
myDGV = CType(Me.Controls(myGridName), DataGridView)
' talk to it like a DGV:
myDGV.Item(0, myGridItemIndex).Value = True
Next
Note: Option Strict would likely require some conversions for the name and index
If the DGV(s) reside in container controls like Panels or Tabs, you have to "find" the control because they will be in that control's collection, not the Form's. Instead of myDGV = CType(Me.Controls(myGridName), DataGridView):
' have the form search for the ctl by name
' the TRUE param tells it to search child controls like panels
Dim tmpArry = Me.Controls.Find(myGridName, True)
' test for a return
If tmpArry.Length > 0 Then
' tmpArry will be Type Control, so cast it
myDGV = CType(tmpArry(0), DataGridView)
End If
This is usually better from the start so you do not have to remember how the form is laid out when coding.

Access a form's control by name

not sure whether the title of this post is accurate.
I'm trying to access windows form controls and their properties by "composing" their name within a loop, but I can't seem to find the related documentation. Using VB.net. Basically, say I have the following:
Dim myDt As New DataTable
Dim row As DataRow = myDt.NewRow()
row.Item("col01") = Me.label01.Text
row.Item("col02") = Me.label02.Text
'...
row.Item("colN") = Me.labelN.Text
I'd like to write a for loop instead of N separate instructions.
While it's simple enough to express the left-hand side of the assignments, I'm stumped when it comes to the right-hand side:
For i As Integer = 1 to N
row.Item(String.format("col{0:00}", i)) = ???
' ??? <- write "label" & i (zero-padded, like col) and use that string to access Me's control that has such name
Next
As an extra, I'd like to be able to pass the final ".Text" property as a string as well, for in some cases I need the value of the "Text" property, in other cases the value of the "Value" property; generally speaking, the property I'm interested in might be a function of i.
Cheers.
You could use the ControlsCollection.Find method with the searchAllChildren option set to true
For i As Integer = 1 to N
Dim ctrl = Me.Controls.Find(string.Format("label{0:00}", i), True)
if ctrl IsNot Nothing AndAlso ctrl.Length > 0 Then
row.Item(String.format("col{0:00}", i)) = ctrl(0).Text
End If
Next
An example on how to approach the problem using reflection to set a property that you identify using a string
Dim myLabel As Label = new Label()
Dim prop as PropertyInfo = myLabel.GetType().GetProperty("Text")
prop.SetValue(myLabel, "A Label.Text set with Reflection classes", Nothing)
Dim newText = prop.GetValue(myLabel)
Console.WriteLine(newText)

im having syntax issues pulling data from 6 text boxes with identical names (other than a number at the end) in a for loop

I have 6 different text boxes with similar names:
txtBox1, txtBox2....txtBox6
I also have an array:
dim intValue (0 to 5) as Integer
Now I want to use a for loop to assign the value in each text box to a corresponding space in the array, concatenating the value of the loop counter with the string "txtBox" and retrieving the data using the .text method.
here is my code:
For count As Integer = 0 To 5
Dim strCount As String = count
Dim strTxtBox As String = "txtBox" & strCount
intValues(count) = Convert.toInt32(strTxtBox.Text)
Next
the issue is that the string name doesn't point to txtBox1, txtBox 2 etc.
Thanks in advance for the help.
If you want to access the control name, you have to use the property "Name".
You should try something like that:
For i As Integer = 0 To 5
For Each c As Control In Controls
If c.Name = "txtBox" & i Then
intValue(i) = Convert.ToInt32(c.Text)
End If
Next
Next i
The above code is just an example, but it should work for you.
Anyway you can write a better code checking the type of the control or maybe using a different loop logic, but the basic idea is that if you want to use in your code the name od the control you have to use the NAME property.
strTxtBox is a string, nothing more. You cannot refer to control names by String without special code. Rather than go down that path, I'd create an array and populate it with text boxes:
Dim txtBoxes As TextBox() = {txtBox1, txtBox2, txtBox3, txtBox4, txtBox5, txtBox6}
Dim intValues As Integer(0 To 5)
For count As Integer = 0 To 5
intValues(count) = Convert.ToInt32(txtBoxes(count).Text)
Next
The easiest way is to iterate through the contents of Controls to find the textboxes. You can either:
Use the .Tag property to label textboxes to identify them, or as the other answer points out, use the .Name property.
If you have a lot of other controls on the form, and they may not be in order, you could also check each control to see if it's a textbox. Assume they are in reverse order, as the Controls array goes from end to beginning.
Dim nums() As Integer = {10, 20, 30, 40, 50, 60}
Dim ctrl As Control
For Each ctrl In Me.Controls
If TypeOf (ctrl) Is TextBox Then
ctrl.Text = nums(Val(ctrl.Name(ctrl.Name.Length - 1)) - 1)
End If
Next
You could also instantiate an array of textboxes programmatically, but you'd have to set all of the placement, etc. by hand.
As I commented on the answer below, you may need to cast the ctrl to a System.Web.UI.Control to access the .Name, using DirectCast.