How do i get data from a textbox that is made during the runtime of the program? - vb.net

this is my code its the start of a customer details editing system for my course work
Public Class editCustomerFields
Dim textbox As New TextBox
Private Sub editCustomerFields_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim updownLBL As Integer = 55
Dim updownTXT As Integer = 80
Dim leftRight As Integer = 30
For i = 0 To globalVariables.countForCustomerDetails - 1
Dim label As New Label
label.Size = New System.Drawing.Size(159, 23)
label.Location = New System.Drawing.Point(leftRight, updownLBL)
label.Text = globalVariables.fieldsCustomerDetailsArray(globalVariables.editCustomerDetailsTxtNamesList.Item(i))
label.Name = globalVariables.fieldsCustomerDetailsArray(globalVariables.editCustomerDetailsTxtNamesList.Item(i))
Me.Controls.Add(label)
TextBox.Size = New System.Drawing.Size(315, 30)
TextBox.Location = New System.Drawing.Point(leftRight, updownTXT)
textbox.Name = globalVariables.fieldsCustomerDetailsArray(globalVariables.editCustomerDetailsTxtNamesList.Item(i))
MsgBox(TextBox.Name)
Me.Controls.Add(textbox)
globalVariables.txtEditCustomerDetailsArray(i) = textbox.Name
updownLBL += 60
updownTXT += 60
If updownTXT >= 500 Then
leftRight = 350
updownTXT = 80
updownLBL = 55
End If
Next
End Sub
End Class
i have a bunch of checkboxes that the user selects that correspond to the different fields in the database. then the program takes the input and on another form displays textboxes and labels for the user to enter data into. How do I get the data entered in the textbox?
fieldsCustomerDetailsArray is an array of the field names ("username","password" etc)
editCustomerDetailsTxtNamesList is a list of the checkboxes for the array to use

Related

How to create a Loop to push Values to different TextBox with Similar Labels names and Change their text?

I am new to this VB. I'm building an application where I need to fill some 48 text boxes with 4 sets of similar names like
L1onHHxx
L1onMMxx
L1offHHxx
L1offMMxx
Where xx is a number from 1 to 24 for each label.
What I'm trying to do is calculate some values based on the user input and fill the text boxes with results.
Private Async Sub Line1Calc_Click(sender As Object, e As EventArgs) Handles Line1Calc.Click
Dim Cycle_Time As Integer
Dim Cycle_Count As Integer
Dim srtHH As Integer
Dim srtMM As Integer
Dim stpHH As Integer
Dim stpMM As Integer
Dim inDelay As Integer
Dim i As Integer
Dim lineONHH As New Label
Dim lineONMM As New Label
Dim lineOFFHH As New Label
Dim lineOFFMM As New Label
'Dim controls = GetAllTextBoxes(Me)
'Line1Tab
Cycle_Time = CInt(L1Time.Text)
Cycle_Count = CInt(L1Count.Text)
srtHH = CInt(L1ONHH.Text)
srtMM = CInt(L1ONMM.Text)
stpHH = CInt(L1OFFHH.Text)
stpMM = CInt(L1OFFMM.Text)
inDelay = (24 / CInt(Cycle_Count))
L1onhh1.Text = srtHH
L1onhh1.Text = srtHH
L1offhh1.Text = stpHH
L1offmm1.Text = stpMM
For i = 2 To (Cycle_Count)
srtHH += inDelay
stpHH += inDelay
lineONHH.Name = "L1onhh" & i.ToString()
lineONMM.Name = "L1onmm" & i.ToString()
lineOFFHH.Name = "L1offhh" & i.ToString()
lineOFFMM.Name = "L1offmm" & i.ToString()
lineONHH.Text = srtHH
lineONMM.Text = srtMM
lineOFFHH.Text = stpHH
lineOFFMM.Text = stpMM
' To Check if the labels name are correct
Box1.Text = lineONHH.Name
Box2.Text = lineONMM.Name
Box3.Text = lineOFFHH.Name
Box4.Text = lineOFFMM.Name
Await Task.Delay(1000)
Next
End Sub
Here when I pass the value of the New label to Box 1,2,3 & 4 for test purposes they are correct but the values don't appear on the respective text boxes.
Please can anyone point me in the right direction of what I'm doing wrong?
This should get you close, with a few assumptions made.
It assumes you have constant textbox naming pattern.
Assumes you want hour and minute in string.
Switch that structure to a DateTime if you want it in that format.
'class to hold all your time value entries
Private Class TimeValue
Public Property HourValue As String
Public Property MinValue As String
End Class
'class for each control time slow and its associated timevalues
Private Class ControlTime
Public Property TimeSlot As String
Public Property OnValue As TimeValue
Public Property OffValue As TimeValue
End Class
'method to set control values
Private Function SetControlValus(controlTimeItem As ControlTime) As Boolean
'find the control
Dim OnHourTextBox As TextBox = DirectCast(Me.Controls.Find(String.Concat("L1onHH", controlTimeItem.TimeSlot), False)(0), TextBox)
OnHourTextBox.Text = controlTimeItem.OnValue.HourValue
Dim OnMinTextBox As TextBox = DirectCast(Me.Controls.Find(String.Concat("L1onMM", controlTimeItem.TimeSlot), False)(0), TextBox)
OnMinTextBox.Text = controlTimeItem.OnValue.MinValue
Dim OffHourTextBox As TextBox = DirectCast(Me.Controls.Find(String.Concat("L1offHH", controlTimeItem.TimeSlot), False)(0), TextBox)
OffHourTextBox.Text = controlTimeItem.OffValue.HourValue
Dim OffMinTextBox As TextBox = DirectCast(Me.Controls.Find(String.Concat("L1offMM", controlTimeItem.TimeSlot), False)(0), TextBox)
OffMinTextBox.Text = controlTimeItem.OffValue.MinValue
Return True
End Function
Private Sub Test()
'set up some results
Dim results As List(Of ControlTime) = New List(Of ControlTime)
results.Add(New ControlTime() With {.TimeSlot = "01",
.OnValue = New TimeValue() With {.HourValue = "08", .MinValue = "56"},
.OffValue = New TimeValue() With {.HourValue = "08", .MinValue = "58"}})
results.Add(New ControlTime() With {.TimeSlot = "02",
.OnValue = New TimeValue() With {.HourValue = "09", .MinValue = "14"},
.OffValue = New TimeValue() With {.HourValue = "09", .MinValue = "29"}})
For Each controlTimeItem In results
SetControlValus(controlTimeItem)
Next
End Sub
Private Sub TestControlTimeButton_Click(sender As Object, e As EventArgs) Handles TestControlTimeButton.Click
Try
Test()
Catch ex As Exception
MessageBox.Show(String.Concat("An error occurred: ", ex.Message))
End Try
End Sub

How to dynamicallty create multiple controls at runtime

I am trying to add multiple labels to a userform at runtime
It's for the player names of a board game; and until the game starts the number of players are not known. I have managed to figure out for myself how to use the dynamic array function to create the list of players. I used a For.....Next loop to add the player names. I thought I could do that to add the labels to the form, but it only adds one. Depending on where the new control type is declared, it either adds the first player only, or the last player
This code produces one label only within the groupbox, the last player
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim Players_Num As Integer = InputBox("Enter the number of players")
Dim Players(Players_Num) As String
Dim newText As New Label
For i = 0 To Players_Num - 1
Players(i) = InputBox("Enter player name")
Next
'This piece of code was jsut for me to test that I was successfully using a For...Loop
'to add the players names, and will be deleted later on
For x = 0 To Players_Num - 1
MessageBox.Show(Players(x))
Next
For z = 0 To Players_Num - 1
newText.Name = "txt" & Players(z)
newText.Text = Players(z)
newText.Size = New Size(170, 20)
newText.Location = New Point(12 + 5, 12 + 5)
GroupBox1.Controls.Add(newText)
Next
End Sub
End Class
This one places only the first player
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim Players_Num As Integer = InputBox("Enter the number of players")
Dim Players(Players_Num) As String
For i = 0 To Players_Num - 1
Players(i) = InputBox("Enter player name")
Next
'This piece of code was jsut for me to test that I was successfully using a For...Loop
'to add the players names, and will be deleted later on
For x = 0 To Players_Num - 1
MessageBox.Show(Players(x))
Next
For z = 0 To Players_Num - 1
Dim newText As New Label
newText.Name = "txt" & Players(z)
newText.Text = Players(z)
newText.Size = New Size(170, 20)
newText.Location = New Point(12 + 5, 12 + 5)
GroupBox1.Controls.Add(newText)
Next
End Sub
End Class
I've tried this in vs 2015 and 2019 Community
Where is it going wrong?
From the looks of the code, you are correctly creating the controls but their location is the same for all of them, essentially, they are being place one of top of the other, the first is hidden with the second, which is hidden with the third.
The line
newText.Location = New Point(12 + 5, 12 + 5)
needs to be modified to place the labels at different locations.
Perhaps, something like:
newText.Location = New Point(12 + 5, 12 + (z * 25))
This will vertically align the labels with a gap of 25 between them
You are placing them all in the same location
newText.Location = New Point(12 + 5, 12 + 5)
Use your 'z' index to place them at different locations in order to be able to see them
For me it is easier to contain controls in a TableLayoutPanel then add the TLP to what ever control collection, such as a GroupBox This way you can couple a Label with TextBox, for example. Here's an example how you can create controls from a DataTable. In your case you would only need 1 ColumnStyle for labels, I just thought I would show you a good practice for future shortcuts. (I rarely use the designer to place controls)
'Start test data
Dim DtTable As New DataTable
With DtTable
Dim NewDtRow As DataRow = .NewRow
For i As Integer = 0 To 25
Dim DtCol As New DataColumn With {.ColumnName = "Col" & i, .DataType = GetType(String)}
.Columns.Add(DtCol)
NewDtRow(DtCol.ColumnName) = "Test" & i
Next
.Rows.Add(NewDtRow)
End With
'End test data
Dim TLP1 As New TableLayoutPanel With {.Name = "TlpFields"}
With TLP1
.BorderStyle = BorderStyle.Fixed3D
.CellBorderStyle = TableLayoutPanelCellBorderStyle.Inset
.AutoScroll = True
.AutoSize = True
.RowStyles.Clear()
.ColumnStyles.Clear()
.Dock = DockStyle.Fill
.ColumnCount = 2
.ColumnStyles.Add(New ColumnStyle With {.SizeType = SizeType.AutoSize})
End With
For Each DtCol As DataColumn In DtTable.Columns
With TLP1
.RowCount += 1
.RowStyles.Add(New RowStyle With {.SizeType = SizeType.AutoSize})
'create labels
.Controls.Add(New Label With {
.Text = DtCol.ColumnName,
.Anchor = AnchorStyles.Right}, 0, .RowCount)
'create textboxs
Dim TxtBox As New TextBox With {
.Name = "TextBox" & DtCol.ColumnName,
.Size = New Size(170, 20),
.Anchor = AnchorStyles.Left}
'add binding
TxtBox.DataBindings.Add("Text", DtTable, DtCol.ColumnName)
.Controls.Add(TxtBox, 1, .RowCount)
End With
Next
Controls.Add(TLP1)

Read data from dynamically created text-box

I'm trying to collect data after creating dynamic text-box with vb.net
Private Sub btn_OK_lines_number_Click(sender As Object, e As EventArgs)
Handles btn_OK_lines_number.Click
Dim i As Integer
Dim x As Integer
Dim Z As Integer
Z = 150
If IsNumeric(txt_lines_number.Text) Then
Int32.TryParse(txt_lines_number.Text, x)
For i = 1 To x
Dim newTB As New TextBox
Dim newLB As New Label
newLB.Name = "lbl_workstation_number_line" & i
newLB.Text = "Nbr Work Station in Line" & i
newLB.Size = New Size(190, 20)
newLB.ForeColor = Color.White
newLB.Font = New Font("consolas", 12, FontStyle.Regular, GraphicsUnit.Pixel)
newLB.Location = New Point(20, Z + i * 30)
newTB.Name = "Textbox" & i
newTB.Size = New Size(170, 20)
newTB.Location = New Point(200, Z + i * 30)
Me.Controls.Add(newTB)
Me.Controls.Add(newLB)
Next
i = i + 1
Else
MessageBox.Show("please enter a number")
txt_lines_number.Text = ""
End If
End Sub
Let's say you just have one row, and only create one TextBox. You set the name here:
newTB.Name = "Textbox" & i
where the resulting TextBox is named Textbox1. The problem is you can't just reference the identifier Textbox1 directly in your code, as you do with txt_lines_number. You can't even reference it as a member of the class (Me.Textbox1). This name didn't exist at compile time, and so it's not an identifier you can use, and it's not a member of the class at all. There was never a matching Dim statement for that name.
What you can do, though, is look again in the Controls collection where you added the TextBox to the form:
Me.Controls("Textbox1")
or
Me.Controls("Textbox1").Text
You may also need to cast the value to a TextBox:
Dim box As TextBox = DirectCast(Me.Controls("Textbox1"), TextBox)
MessageBox.Show(box.Text)
Remember that case matters here.
Further saving this in a DB is out of scope for one question. There are as many ways to do that as there are programmers in the world. You should make your own attempt first, and come back here with a new question when you run into specific problems.
Thank you,
this is my attempt and it is done !
Dim userInput As TextBox = Form1.Controls.Item("TextBox" & i.ToString)
mycommand.Parameters.AddWithValue("#workstation", userInput.Text)
:D
Because you creating dynamic amount of input controls, right tool for the job will be DataGridView control.
Create a class to represent your data
Public Class LineInfo
Public Property Number As Integer
Public Property WorkStationNumber As Integer
End Class
Create `DataGridView in the form designer.
Private Sub btn_OK_lines_number_Click(sender As Object, e As EventArgs) Handles btn_OK_lines_number.Click
Dim linesAmount As Integer
If Integer.TryParse(txt_lines_number.Text, linesAmount) = False Then
MessageBox.Show("please enter a number")
txt_lines_number.Text = ""
Exit Sub
End If
' Create class instance for every line
Dim lines =
Enumerable.Range(1, linesAmount)
.Select(Function(i) New LineInfo With { .Number = i })
.ToList()
'Set lines as DataSource to the DataGridView
Me.DataGridView1.DataSource = lines
End Sub
DataGridView will display all lines and provide input fields to update work station numbers.
You can access updated lines later by casting DataSource back to the List
Dim lines = DirectCast(Me.DataGridView1.DataSource, List(Of LineInfo))
' Now you can access all data and save it to the database
Dim parameters =
lines.Select(Function(line)
Return new SqlParameter With
{
.ParameterName = $"#workstation{line.Number}",
.SqlDbType = SqlDbType.Int,
.Value = line.WorkStationNumber
}
End Function)
.ToList()
myCommand.Parameters.AddRange(parameters)
You can freely change style, font colors of different columns in the datagridview.

Problems with generating labels

The Problem: I'm programmatically generating labels but am having trouble referencing them in code because they don't exist at runtime.
The Context: For a game, I've generated a 10x10 grid of labels with the following:
Public lbl As Label()
Dim tilefont As New Font("Sans Serif", 8, FontStyle.Regular)
Private Sub Lucror_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim i As Integer = 0
Dim a As Integer = 0
Dim height As Integer
Dim width As Integer
height = 30
width = 30
ReDim lbl(99)
For i = 0 To 99
lbl(i) = New Label
lbl(i).Name = i
lbl(i).Size = New System.Drawing.Size(30, 30)
lbl(i).Location = New System.Drawing.Point((width), height)
lbl(i).Text = i
lbl(i).Font = tilefont
Me.Controls.Add(lbl(i))
width = width + 30
a = a + 1 'starting new line if required
If (a = 10) Then
height = height + 30
width = 30
a = 0
End If
Next
End Subenter code here
This worked fine but the labels function as tiles in the game and game tiles need to store 2-3 integers each as well as be able to be referenced through event handlers. I figured a possible way to store integers would be to generate 100 arrays, each named after a label and each holding the 2-3 integers, but that seems very redundant.
What I need:
On click and on hover event handlers for every label
An array (or dictionary?) to store 2-3 integers for every label
Labels have to reference each others names ie. do something to label with name (your name + 1).
The Question: Is there a simple way to achieve these three things with the current way I generate labels (and if so, how?) and if not, how else can I generate the 100 labels to make achieving these things possible?
Any help is much appreciated.
Your labels do exist at runtime, but not at compile time. Attaching events is a little different at runtime, you must use AddHandler.
Below is some sample code that should illustrate everything you're asking for. I've introduced inheritance as a way of saving data that is pertinent to each tile. The GameTile type behaves exactly as a label, and we've added some functionality for storing integers and naming the control.
Public Class Form1
Dim tilefont As New Font("Sans Serif", 8, FontStyle.Regular)
Public Property GameTiles As List(Of GameTile)
Private Sub Lucror_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim a As Integer = 0
Dim xPosition As Integer = 30
Dim yPosition As Integer = 30
GameTiles = New List(Of GameTile)
For i = 0 To 99
Dim gt As New GameTile(i.ToString)
gt.Size = New System.Drawing.Size(30, 30)
gt.Location = New System.Drawing.Point((yPosition), xPosition)
gt.Font = tilefont
gt.Integer1 = i + 1000
gt.Integer2 = i + 2000
gt.Integer3 = i + 3000
Me.Controls.Add(gt)
AddHandler gt.Click, AddressOf TileClickHandler
GameTiles.Add(gt)
yPosition = yPosition + 30
a = a + 1 'starting new line if required
If (a = 10) Then
xPosition = xPosition + 30
yPosition = 30
a = 0
End If
Next
End Sub
Private Sub TileClickHandler(sender As Object, e As EventArgs)
Dim gt = CType(sender, GameTile)
MsgBox("This tile was clicked: " & gt.Text &
Environment.NewLine & gt.Integer1 &
Environment.NewLine & gt.Integer2 &
Environment.NewLine & gt.Integer3)
End Sub
End Class
Public Class GameTile
Inherits Label
'this class should be in a separate file, but it's all together for the sake of clarity
Public Property Integer1 As Integer
Public Property Integer2 As Integer
Public Property Integer3 As Integer
Public Sub New(NameText As String)
MyBase.New()
Name = NameText
Text = NameText
End Sub
End Class

How to get the value of a textbox from sa MDI form Groupbox?

I'm new to vb.net and always searching for solution. My forms involved are MainMenu, poCustom, and rdlcForm. All are working well until I got a new look with MDI Forms.
My "New" MainMenu are now containing the poCustom into a Groupbox. Which I searched the code as
For Each f As Form In Application.OpenForms
If TypeOf f Is poCustom Then
f.Activate()
Return
End If
Next
Dim ch As New poCustom
ch.TopLevel = False
ch.Visible = True
ch.StartPosition = FormStartPosition.Manual
Dim leftStart As Integer = 1220 - (ch.Width + (SystemInformation.Border3DSize.Width * 2))
Dim topStart As Integer = 670 - (ch.Height + (SystemInformation.Border3DSize.Height * 2))
ch.Location = New Point(leftStart, topStart)
GroupBox1.Controls.Add(ch)
Problem: The rdlcForm(report) cannot get the value of textboxes in poCustom form. Code below:
Private Sub rptPOView2_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim rptParam1(11) As Microsoft.Reporting.WinForms.ReportParameter
rptParam1(0) = New Microsoft.Reporting.WinForms.ReportParameter("rptDate", poCustom.Label1.Text)
rptParam1(1) = New Microsoft.Reporting.WinForms.ReportParameter("rptREF", poCustom.Label5.Text)
rptParam1(2) = New Microsoft.Reporting.WinForms.ReportParameter("rptCompany", poCustom.CompanyName.Text)
rptParam1(3) = New Microsoft.Reporting.WinForms.ReportParameter("rptQTY", poCustom.txBoxQTY.Text)
rptParam1(4) = New Microsoft.Reporting.WinForms.ReportParameter("rptUOM", poCustom.txBoxUOM.Text)
rptParam1(5) = New Microsoft.Reporting.WinForms.ReportParameter("rptDesciption", poCustom.txBoxDesc.Text)
rptParam1(6) = New Microsoft.Reporting.WinForms.ReportParameter("rptUnit", poCustom.txBoxUnit.Text)
rptParam1(7) = New Microsoft.Reporting.WinForms.ReportParameter("rptTotal", poCustom.txBoxTotal.Text)
rptParam1(8) = New Microsoft.Reporting.WinForms.ReportParameter("rptSubTotal", poCustom.Label25.Text)
rptParam1(9) = New Microsoft.Reporting.WinForms.ReportParameter("rptVAT", poCustom.Label26.Text)
rptParam1(10) = New Microsoft.Reporting.WinForms.ReportParameter("rptTotalAmount", poCustom.Label27.Text)
rptParam1(11) = New Microsoft.Reporting.WinForms.ReportParameter("rptRequest", poCustom.Label30.Text)
ReportViewer1.LocalReport.SetParameters(rptParam1)
Me.ReportViewer1.RefreshReport()
TextBox1.Text = poCustom.CompanyName.Text
End Sub
Which happens to work without using MDI Forms. I would like to know the cause of the problem for future use. Thank you in advance!
You are using two different instances of poCustom. ch is the first, and you populate its textboxes. But on the rptPOView2_Load event, you are using the other instance, which contains textboxes that has no value yet. One way to fix the problem is to use poCustom itself and not ch.
poCustom.TopLevel = False
poCustom.Visible = True
poCustom.StartPosition = FormStartPosition.Manual
Dim leftStart As Integer = 1220 - (ch.Width + (SystemInformation.Border3DSize.Width * 2))
Dim topStart As Integer = 670 - (ch.Height + (SystemInformation.Border3DSize.Height * 2))
poCustom.Location = New Point(leftStart, topStart)
GroupBox1.Controls.Add(poCustom)