How to get value from dynamically created texboxes? - vb.net

im new here and im having some problem with my vb.net code. I have dynamically created few textboxes on panel, and I want my code after submitting the form to save those values into database. Problem is that I just cannot find the way how to grab values from those texboxes. I tried everything that i found on internet but i still getting the error message "Object reference not set to an instance of an object". Can someone advice me what am i doing wrong.
Here is the code how i created texboxes:
for i As Integer = 0 To cntPos -1
Dim txtJobTo as TextBox = new TextBox()
txtJobTo.ID = "txtJobTo_" & jobID
Dim label as Label = new Label()
label.text = posPanel.Rows(i).Item("Position")
pnlContainer.Controls.Add(label)
pnlContainer.Controls.Add(new LiteralControl("</td><td>"))
pnlContainer.Controls.Add(txtJobTo)
next
This line of code is shows those texboxes on page
<tr bgcolor="#FFCC99"><td colspan="4">
<asp:Panel ID="pnlContainer" runat="server" Visible="true"></asp:Panel></td></tr>
<tr><td colspan='6' align='center'> <asp:Button ID="cmdSave" Text="Save" ToolTip="cmdSave" CommandArgument="cmdSave_Click" runat="server" /></td></tr>
And this is part of the code that should save all data
Sub cmdSave_Click(ByVal sender As System.Object, e As EventArgs) Handles cmdSave.Click
...
for i As Integer = 0 To cntPosIns -1
Dim strTo as TextBox = New TextBox()
posID = posIns.Rows(i).Item("ID_Pos")
strTo.Text =CType(pnlContainer.FindControl("txtJobTo_" & posID.ToString()),TextBox).Text
....
'Insert into database
next
I always get error message on this line strTo.Text =CType(pnlContainer.FindControl("txtJobTo_" & posID.ToString()),TextBox).Text
Can someone please give me some advice on how to fix this? What is the proper way to read value from dynamically created textboxes in this situation?
Thank you

there are two aspects to this I think. Dynamic controls are a bit of a minefield and can take a while to understand.
a) Make sue to create the dynamic controls and add them to the page during OnInit or CreateChildControls. Access the value in the event handler or during OnPreRender...otherwise you will have trouble using the standard TextBox.Text property to get the value. It's tricky using dynamic controls because the values are not present for the whole page lifecycle without inspecting the page.request property.
b) Personally, when I dynamically create input elements, I don't "let go" of them and rely on findControl to get a handle back onto them for me.
When I create controls dynamically, I store them in a look up e.g. a lovely Dictionary(of string, TextBox) which is accessible to the rest of the code, e.g. a property or member variable.
' Lookup declared outside of the consuming methods so it is accessible to both
private dictControlsLookup as new dictionary(of string, textbox)
Sub YourSubName
for i As Integer = 0 To cntPos -1
Dim txtJobTo as TextBox = new TextBox()
txtJobTo.ID = "txtJobTo_" & jobID
Dim label as Label = new Label()
label.text = posPanel.Rows(i).Item("Position")
pnlContainer.Controls.Add(label)
pnlContainer.Controls.Add(new LiteralControl("</td><td>"))
pnlContainer.Controls.Add(txtJobTo)
dictControlsLookup.Add(txtJobTo.ID, textJobTo)
next
End Sub
Sub cmdSave_Click(ByVal sender As System.Object, e As EventArgs) Handles cmdSave.Click
...
for i As Integer = 0 To cntPosIns -1
Dim strTo as TextBox = New TextBox()
posID = posIns.Rows(i).Item("ID_Pos")
dim ctlId as string = "txtJobTo_" & posID.ToString()
If dictControlsLookup.ContainsKey(ctlId) Then
strTo.Text = dictControlsLookup(ctlId).Text
End If
....
'Insert into database
next
End Sub
Alternatively you could just iterate the dictControlsLookup.Values collection in save_click to access all the text boxes :-)

Related

How can I use a variable to reference a textbox?

I'm new to visual basic and programming in general, but I'm trying to make a statistic counter sort of program. I'm trying to use a variable to reference a textbox, for example, k_kills(i) = txtKills(i).Text. This doesn't work, however, so I then tried the following:
For i = 0 To 8
Dim tempBox As TextBox
Dim tempName As String = "txtKills" & i.ToString
tempBox = Me.Controls.Item(tempName)
k_kills(i) = tempBox.Text
Next
This also doesn't work and spits out an error each time saying that 'tempBox was Nothing'.
Can anyone tell me if I can make this work?
Thanks.
You will need to find the control in some collection. By default the control would exist in its parent's Controls property and since you're trying to get the control by its name then you could use ControlCollection's Find method. If you can guarantee that the control's parent is the Form then you'd call:
Dim tempBox As TextBox = DirectCast(Me.Controls.Find(tempName, False), TextBox)
But if there is the possibility that the control's parent is something other than the Form then you'd call:
Dim tempBox As TextBox = DirectCast(Me.Controls.Find(tempName, True), TextBox)
The first would execute slightly quicker because it only iterates over the current ControlCollection whereas the second could take longer because if it cannot find the control in the current ControlCollection then it starts to iterate over the child controls as well.
Assuming the controls are all in Form as parent and they all start with txtKills...
If you are going to use these text boxes as a group for several actions you may want to build an array or list of TextBox.
Dim Kills(7) As TextBox
Private Sub CreateTextBoxArray()
Dim index As Integer
For Each ctrl As Control In Controls
If ctrl.Name.StartsWith("txtKills") Then
Kills(index) = DirectCast(ctrl, TextBox)
index += 1
End If
Next
End Sub
Private Sub ClearKillTextBoxes()
For Each t In Kills
t.Clear()
Next
End Sub
Private Function GetTextFromKillBoxes() As List(Of String)
Dim lst As New List(Of String)
For Each t In Kills
lst.Add(t.Text)
Next
Return lst
End Function
After Mary's comment I edit my answer to add this line --> My code does not work if Option Strict is On and 'For' starting in 0 or 1 or any number and txtKills[X] exists.
This was my previous answer and I don't know if I have to delete or not:
Your code works fine but I think you have an error because your For starts in 0 and you don't have any "txtKills0". I've tested it now:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim k_kills(10) As String '<< Ignore the length
For i = 1 To 7
Dim tempBox As TextBox
Dim tempName As String = "txtKills" & i.ToString
tempBox = Me.Controls.Item(tempName)
k_kills(i) = tempBox.Text
MsgBox(k_kills(i))
Next
End Sub

is there any way to simplify this code? vb.net [duplicate]

i have been created buttons and textboxs by coding in next loop,
the result
'T(x).Name = "text_1"
'T(x).Name = "text_2"
'T(x).Name = "text_3"
'....
'B(x).Name = "button_1"
'B(x).Name = "button_2"
'B(x).Name = "button_3"
'...
and i want to get textbox property whene i click the button,
i can get button property when click like button_1.Name.ToString
but i cant get the text_1,2,3 .... property.
i do some trick by split function button_1.Name.ToString and get the last number
and add it to the textbox name like "text_" & button_1.Name.ToString but i can't convert this string to object.
Update
Here's the code I'm using to load the controls in the loop:
C_A_TEXT(x) = New TextBox()
C_A_TEXT(x).Dock = System.Windows.Forms.DockStyle.Fill
C_A_TEXT(x).Location = New System.Drawing.Point(270, 5)
C_A_TEXT(x).Margin = New System.Windows.Forms.Padding(0)
C_A_TEXT(x).Size = New System.Drawing.Size(70, 27)
C_A_TEXT(x).TabIndex = 5
C_A_TEXT(x).Name = "NEW_RECHARGE_COUNT_TEXT_" & x
Update 2
Here's some more code:
AddHandler C_A_BUTTONS(x).Click, AddressOf C_A_BUTTON
Private Sub C_A_BUTTON(ByVal sender As System.Object, ByVal e As System.EventArgs)
Dim thisButton As Button = sender Dim A = CType(Me.Controls("NEW_RECHARGE_COUNT_TEXT_1"), TextBox)
MsgBox(A.Text.ToString) 'Error!
End Sub
You can access the controls by name via the Form.Controls property, for instance:
Dim text1 As TextBox = CType(Me.Controls("text_1"), TextBox)
As a quick useful tip to note, you don't seem to have to specify the type of control within the CType statement for purposes of accessing a control on your form. I came across this when trying to access multiple types of form controls, such as buttons and textboxes, all with the same line of code.
CType(Controls("NAME_OF_CONTROL"), Control)
Note that, rather than specifying exactly what type of control, such as 'TextBox' or 'Button', you simply state 'Control'. This allows you to universally change any type of control, without needing to specify its type.
I couldn't find this anywhere else, so I thought I'd share it!
Below is the code.
Dim oObj As Object = Me.Controls.Find("control name", True).FirstOrDefault()
Obj.Property = Value
I hope it helps.
Dim sometext As TextBox = CType(Me.Controls("sometext "), TextBox)
The title of the thread and your description of the problem at hand seem a little different from each other.
To answer your title (to find a control by its name) use the following:
Dim myControlToFind = LayoutRoot.FindName("NAMEOFCONTROL")
More information on this method can be found here .
To answer the description of your issue as (to access a code generated control after it is clicked) do the following:
In the loop where you are creating the control(s) add the following handler
Addhandler YOURCONTROL.Clicked, AddressOf Textbox_Clicked
...and then this will handle the click event
Private Sub Textbox_Clicked(sender as object, e as RoutedEventArgs)
Dim tbClicked = Ctype(sender, TextBox)
'You can now access any of the properties of the textbox, for example
Dim txt as String = tbClicked.Text
Dim name as String = tbClicked.Name
Dim height as Double = tbClicked.Height
End Sub
None of the above worked for me. This does:
Dim selVal As String = CType(Form.FindControl(myListName), DropDownList).SelectedValue

adding multiple textbox .net

What i want is when i input a number in texbox1.text like for example i enter 3 it should show 3 textbox but i always get an error. and also i have to save it in database but i dont know how. Help Please..
Private boxes(TextBox1.text) As TextBox
Private Sub Form2_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim newbox As TextBox
For i As Integer = 1 To TextBox1.Text
newbox = New TextBox
newbox.Size = New Drawing.Size(575, 35)
newbox.Location = New Point(10, 10 + 35 * (i - 1))
newbox.Name = "TextBox" & i
newbox.Text = newbox.Name
'connect it to a handler, save a reference to the array and add it to the form controls
AddHandler newbox.TextChanged, AddressOf TextBox_TextChanged
boxes(i) = newbox
Me.Controls.Add(newbox)
Next
End Sub
OK. The error I get when I try to run your code is :-
An unhandled exception of type 'System.InvalidCastException' occurred in Microsoft.VisualBasic.dll
Additional information: Conversion from string "" to type 'Integer' is not valid.`
This is because you're trying to start a loop using a string as the termination index for the loop. Try using
For i As Integer = 1 To Val(TextBox1.Text)
your next problem will depend on how you've declared boxes. If you have declared it like this ..
Dim boxes() As TextBox
You'll end up with a Null reference exception because when you declared boxes, you didnt supply any elements. To remedy this you'll need to add this just before your loop ..
ReDim Preserve boxes(Val(TextBox1.Text))
If boxes is a list.. and to be honest .. thats a better choice than an array, instead of the above line you'll need to change
boxes(i) = newbox
to
boxes.Add(newbox)
You might also need to change other code associated with boxes, but the work will be worth it.
Your biggest problem is that you're trying to get a value from a TextBox that hasn't even appeared yet. You've put your code inside the form's load event. It really needs to be in a separate method. Oh and rather than use the TextBox.changed event you should use a button control to execute the method. Otherwise it's too easy for someone to change the number in the textbox. With your code, each time the textbox is changed (deleting a digit or adding another digit), more TextBoxes will be added and you could end up with lots of them.
So possible final code should look like ..
Public Class Form1
Dim boxes As New List(Of TextBox)
Private Sub Addbuttons(buttonCount As Integer)
Dim newbox As TextBox
For i As Integer = 1 To buttonCount
newbox = New TextBox
newbox.Size = New Drawing.Size(575, 35)
newbox.Location = New Drawing.Point(10, 10 + 35 * (i - 1))
newbox.Name = "TextBox" & i
newbox.Text = newbox.Name
'connect it to a handler, save a reference to the array and add it to the form controls
boxes.Add(newbox)
Me.Controls.Add(newbox)
Next
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Addbuttons(Val(TextBox1.Text))
End Sub
End Class

Autofill TextBox/Checkbox from a previous TextBox' value (VB.NET Database)

Note: I'm using Visual Studio, original work was on SQL Server, moved to VB.NET
I have a Textbox "ViewStatusTxt", next to it there's a Button "ViewStatusBtn"
Below it there's a TextBox "ViewNAMETxt", another TextBox "ViewACTIVITYTxt" and then a Checkbox "ModifyStatusCB"
I'm trying to auto-fill the Checkbox AND the Textbox based on the ID input there, however I really have no clue about it since I'm new to VB.NET
Here's the code used
Private Sub IDSearch(StatusViewBtn As String)
' ADD SEARCH QUERY PARAMETERS - WITH WILDCARDS
SQL.AddParam("#StatusViewBtn", StatusViewBtn)
'RUN QUERY - SEARCH GIVES THOSE RESULTS
SQL.ExecQuery(" SELECT
aID,
Name,
Status,
Activity
FROM
[dbo].[initialTable]
WHERE
aID = #StatusViewBtn
ORDER BY
aID ASC")
End Sub
That's the function's code, which is fully working since it's a smaller version of the same one I used in a Search Page
Here's the button's function, which I'm sure is where I'm having problems, unless I need to add a specific function to the ViewNAMETxt
Private Sub StatusViewBtn_Click(sender As Object, e As EventArgs) Handles StatusViewBtn.Click
IDSearch(StatusViewBtn.Text)
ViewNAMETxt.Text = SQL.ExecQuery("SELECT
Name
FROM
initialTable
WHERE
aID = #StatusViewBtn")
End Sub
And I haven't even started on the Checkbox, viewing how the first one caused me issues. Hopefully the solution would be similar to both of them.
Thanks for reading guys, and sorry for the newbie question
1- Suppose you have a table named YourTable(int KeyColumn, string StringColumn, boolean BooleanColumn)
2- Create a form and put 2 textboxes and a checkbox and a button on it. KeyColumnTextBox, StringColumnTextBox, BooelanColumnCheckBox, SearchButton
3- In click event handler for SearchButton put the codes:
Private Sub SearchButton_Click(sender As Object, e As EventArgs) Handles SearchButton.Click
Dim connection = New SqlConnection("Your Connection string here")
Dim command = New SqlCommand("SELECT StringColumn, BooleanColumn FROM YourTable WHERE KeyColumn=#KeyColumn", connection)
command.Parameters.Add(New SqlParameter("#KeyColumn", Int32.Parse(KeyColumnTextBox.Text)))
connection.Open()
Dim reader = command.ExecuteReader()
While reader.Read()
StringColumnTextBox.Text = reader.GetString(0)
BooleanColumnCheckBox.Checked = reader.GetBoolean(1)
End While
End Sub
Don't forget to Imports System.Data.SqlClient at top of your file.

Vb.Net Control Variable Names

I am trying to create bunch of WebBrowsers with Variable Names; I started with the following code, but seems it has something wrong that I cannot figure our;
The error is in the FIRST PORTION OF THE CODE;
Any help/comment appreciated:
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim NumberOfBrowsers As Integer = 12
For Pro As Integer = 1 To NumberOfBrowsers
Dim frmNew As New Form
'------------------------- FIRST PORTION:
Dim MekdamBrowser As New WebBrowser
MekdamBrowser = "WebBrowser" & Pro
frmNew.Controls.Add(MekdamBrowser)
'-------------------------
MekdamBrowser.Location = New System.Drawing.Point(10, 10)
MekdamBrowser.Size = New System.Drawing.Size(300, 300)
MekdamBrowser.Show()
'-------------------------
Next
End Sub
End Class
Thanks
It seems that you want the first portion to be as follow instead :
'------------------------- FIRST PORTION:
Dim MekdamBrowser As New WebBrowser
MekdamBrowser.Name = "WebBrowser" & Pro
frmNew.Controls.Add(MekdamBrowser)
'-------------------------
The difference between this and the original code you tried is, above code assigns name for WebBrowser control, where corresponding line of code in question tried to "replace" WebBrowser control it self with a name (it tried to assign string data to variable of type WebBrowser which is not a valid operation).