In the form, everytime I click te button, a new textbox has to appear.
I want to make an Array with all of these textboxes.
The problem is, that al these textboxes have a dynamic name.
How do I have to put them in the Array?
Here's my code:
Set nieuwtxtingredient = Me.Controls.Add("Forms.Textbox.1", "Ingredient", True)
With nieuwtxtingredient
.Width = Me.txtIngredient0.Width
.Height = Me.txtIngredient0.Height
.Left = Me.txtIngredient0.Left
.Top = Me.txtIngredient0.Top + 30 * aantalBoxes
.Name = "txtIngredient" + CStr(aantalBoxes)
End With
Dim naam As String
Dim ingredientArray() As String
ReDim ingredientArray(1 To aantalBoxes)
ingredientArray(aantalBoxes) = **Me.txtIngredient0.Value**
In your code, you save a reference to your new textbox in nieuwtxtingredient.
You could save this reference in an array of Textbox and later read the name and value of each one.
This is how I suggest to revise your code :
Dim aantalBoxes As Integer
Dim ingredientArray() As Control
Private Sub btnVoegToe_Click()
Dim aantalRecepten As Integer
Dim Teller As Integer
aantalRecepten = Cells(2, Columns.Count).End(xlToLeft).Column
Cells(2, aantalRecepten + 2).Value = Me.txtNaamRecept.Value
For Teller = 1 To aantalBoxes ' <-- starts at 1, formula below adjusted
Cells(2 + Teller, aantalRecepten + 2).Value = ingredientArray(aantalBoxes).Value
Next Teller
End Sub
Private Sub btnVolgendeIngredient_Click()
aantalBoxes=aantalBoxes + 1 ' <-- must calculate the total
ReDim Preserve ingredientArray(aantalBoxes) ' <-- you had this in the earlier version
Set nieuwtxtingredient = Me.Controls.Add("Forms.Textbox.1", "Ingredient", True)
With nieuwtxtingredient
.Width = Me.txtIngredient0.Width
.Height = Me.txtIngredient0.Height
.Left = Me.txtIngredient0.Left
.Top = Me.txtIngredient0.Top + 30 * aantalBoxes
.Name = "txtIngredient" + CStr(aantalBoxes)
End With
' first Textbox is numbered 1
set ingredientArray(aantalBoxes) = nieuwtxtingredient ' <-- you had this in the earlier version
End Sub
See this example, http://jsfiddle.net/7zkzttpr/2/
$(document).ready(function() {
var max_fields = 10; //maximum input boxes allowed
var wrapper = $(".input_fields_wrap"); //Fields wrapper
var add_button = $(".add_field_button"); //Add button ID
var x = 1; //initlal text box count
$(add_button).click(function(e){ //on add input button click
e.preventDefault();
if(x < max_fields){ //max input box allowed
x++; //text box increment
$(wrapper).append('<div><input type="text" name="mytext[]"/>Remove</div>'); //add input box
}
});
$(wrapper).on("click",".remove_field", function(e){ //user click on remove text
e.preventDefault(); $(this).parent('div').remove(); x--;
})
});
When ever you create a new textbox, give the same name to the textbox as an array so that you can get the values of all textboxes in an array.
Related
This is my first question ever, so please spare me if I did something wrong.
I have a small survey form that automatically draw questions and answers from a SQL server table, and create a question label (Label_Questionnaire(i)), a panel to nest all radiobuttons for the answer of each question (Panel_Response(i)), and 3 radiobuttons(yes, no, n/a), named RadioButton_Answers(i)_1 . All questions and answers are inside a big panel (Panel_Survey) to allow user to scroll up and down (around 50 questions).
When I run the program, I can only see questions but none of the radiobuttons are showing. What I did try are:
Use .BringToFront to bring the Panel_Response and all radiobuttons to front.
Change .Parent to Controls.Add . Instead of using .Parent, I use Panel_Survey.Controls.Add(Panel_Response) and Panel_Response.Controls.Add(RadioButton_Answers_1)
Force Panel_Response.Visible = True and all radiobuttons visible = true
(I know it might sound stupid, but I'm out of trick)
How do I make those radiobuttons show up? If not, are there any better designs for this kind of survey form? Thank you for any advice, in advance!
Below is my code:
Protected Overrides Sub OnLoad(e As EventArgs)
Dim PanelCount As Integer
Dim QuestionName As String
Dim Response1 As String
Dim Response2 As String
Dim Response3 As String
Dim InitialX As Integer = Panel_Survey.Left
Dim InitialY As Integer = Panel_Survey.Top
Dim SizeX As Integer = 1000
Dim SizeY As Integer = 25
'Load the survey
Try
'Get a list of questions and answers into array of list
Dim ListofQuestionandAnswers As New List(Of List(Of String))
Dim conn As New SqlClient.SqlConnection
conn.ConnectionString = ConnectionString
Dim CommandString As String = "SELECT [QuestionID], [QuestionName] ,[Response1],[Response2],[Response3] FROM [Question_List] ORDER BY [QuestionID]"
Dim Command As New SqlClient.SqlCommand
Command.CommandText = CommandString
Command.Connection = conn
Dim dr As SqlClient.SqlDataReader
conn.Open()
dr = Command.ExecuteReader
While dr.Read
Dim ls As New List(Of String)
ls.Add(dr.GetValue(0).ToString)
ls.Add(dr.GetValue(1).ToString)
ls.Add(dr.GetValue(2).ToString)
ls.Add(dr.GetValue(3).ToString)
ls.Add(dr.GetValue(4).ToString)
ListofQuestionandAnswers.Add(ls)
End While
conn.Close()
PanelCount = ListofQuestionandAnswers.Count
For i = 0 To ListofQuestionandAnswers.Count - 1
QuestionName = ListofQuestionandAnswers(i)(1)
Response1 = ListofQuestionandAnswers(i)(2)
Response2 = ListofQuestionandAnswers(i)(3)
Response3 = ListofQuestionandAnswers(i)(4)
Dim Label_Questionnaire As New Label
Dim Panel_Response As New Panel
Dim RadioButton_Answers_1 As New RadioButton
Dim RadioButton_Answers_2 As New RadioButton
Dim RadioButton_Answers_3 As New RadioButton
'Condition the label
With Label_Questionnaire
.Parent = Panel_Survey
.Name = "Label_Questionnaire" + i.ToString
.Font = New Font("Calibri", 11, FontStyle.Regular)
.Text = QuestionName
.ForeColor = Color.Black
.Location = New Point(InitialX, InitialY)
.AutoSize = True
End With
'Condition the panel
With Panel_Response
'Panel_Survey.Controls.Add(Panel_Response)
.Parent = Panel_Survey
.Name = "Panel_Questionnaire" + i.ToString
.Location = New Point(InitialX + 880, InitialY)
.Width = 250
.Height = 25
.BringToFront()
End With
Dim j As Integer
Dim h As Integer
j = Panel_Response.Left
h = Panel_Response.Top
'Condition the radiobuttons for answers
With RadioButton_Answers_1
.Parent = Panel_Response
.Name = "RadioButton_Answers" + i.ToString + "_1"
.Font = New Font("Calibri", 11, FontStyle.Regular)
.Text = Response1
.ForeColor = Color.Black
.Location = New Point(j, h)
.AutoSize = True
h += RadioButton_Answers_1.Height
End With
With RadioButton_Answers_2
.Parent = Panel_Response
.Name = "RadioButton_Answers" + i.ToString + "_2"
.Font = New Font("Calibri", 11, FontStyle.Regular)
.Text = Response2
.ForeColor = Color.Black
.Location = New Point(RadioButton_Answers_1.Right, h)
.AutoSize = True
End With
With RadioButton_Answers_3
.Parent = Panel_Response
.Name = "RadioButton_Answers" + i.ToString + "_3"
.Font = New Font("Calibri", 11, FontStyle.Regular)
.Text = Response3
.ForeColor = Color.Black
.Location = New Point(RadioButton_Answers_2.Right, h)
.AutoSize = True
End With
InitialY = InitialY + SizeY + 10
Next
Catch ex As Exception
MessageBox.Show(String.Format("Error: {0}", ex.Message), "Error while creating questions and answers", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
End Sub
Few basic problems here:
You seem to assume that when a control is placed inside a panel, it must be placed at a location relative to the form. It doesn't; it places relative to the Panel which has its own coordinate system starting at 0,0 in the top left of the panel - you initialize j and h (for locations of the radio buttons) to the Left and Top of the panel they're in, but they should be inited to 0,0 if you want the radiobuttons to start at the top left of the panel. If the Panel is placed at 300,300 on a form, and you place a radiobutton inside the panel also at 300,300 (because you copied its left and top) then the radio button will look like it's at 600,600 on the form because its at 300,300 inside a panel that is at 300,300
You only make your panel 250 wide - it's barely wide enough to show a single radio button
You increment h once, by an amount that means the next radiobutton disappears off the bottom of the panel (which is 25 pixels high)
Here:
With Panel_Response
'Panel_Survey.Controls.Add(Panel_Response)
.Parent = Panel_Survey
.Name = "Panel_Questionnaire" + i.ToString
.Location = New Point(InitialX + 880, InitialY)
.Width = 2500
.Height = 25
.BringToFront()
.BackColor = Color.Red
End With
Dim j As Integer
Dim h As Integer
j = 0
h = 0
Paste that over your app code and run it again. I made the panel BackColor red so you can more easily see where the panel is
I guess you need to decide how you want your UI to look. If the radiobuttons are laid out vertically, don't increment X when you add them to the panel (by setting the parent property). Make the panel tall enough to accommodate them (25 px not enough)
Use a FlowLayoutPaanel or TableLayoutPanel instead
I have a userform as following:
When I pick the database I want and click select, it gets me to the other page:
All those checkboxes are created depending on the output of an sql query.
In this example, the SQL query is:
ID NAME
8 AI_EQ
14 BB_EQ
19 DM_EQ
22 GD_EQ
and so on...
I am adding the checkboxes in the select button as following (from a record set rst):
'creating checkboxes
If Not rst.EOF And Not rst.BOF Then
rst.MoveFirst
i = 0
Do
With MultiPage1.Pages(1).Controls.Add("Forms.Checkbox.1", "Checkbox" & i)
.Top = yPos
.Left = 7
.Caption = rst![name]
.Width = 450
.Height = 24
.WordWrap = True
.Value = False
yPos = yPos + 17
i = i + 1
rst.MoveNext
End With
Loop Until rst.EOF
End If
rst.Close
cnn.Close
Set rst = Nothing
Set cnn = Nothing
Then, I would want the Finish button considering whatever checkboxes the user selects. For example, if he selects the first two, I would want to have "8,14" ID, so that I can add them into a new SQL query.
I guess I have to create an array to achieve this instead of just having rst![name]. But my attempts of creating it have failed, and even if I had the array correctly, I wouldn't know how to adapt it to have it return the ID when selecting the NAME.
This is how I am trying to create the array (but it is not returning anything)
Dim MyArray() As Variant
For i = 0 To rst.RecordCount
MyArray = rst.GetRows(i)
rst.MoveNext
Next
Any hints/help would be appreciated.
Since the checkboxes are created dynamically, do this.
Loop through all controls and check if they are checkbox or not
Check if they are checked
Check if they have something in .Tag and store it in a variable.
Code
Private Sub CommandButton1_Click()
Dim cCont As Control
Dim cbString As String
For Each cCont In Me.Controls
If TypeName(cCont) = "CheckBox" Then
If cCont.Value = True Then
If cCont.Tag <> "" Then
If cbString = "" Then
cbString = cCont.Tag
Else
cbString = cbString & "," & cCont.Tag
End If
End If
End If
End If
Next cCont
Debug.Print cbString
End Sub
But for this to work, when you are creating the checkbox, set the .Tag property to the ID value.
With MultiPage1.Pages(1).Controls.Add("Forms.Checkbox.1", "Checkbox" & i)
'
'~~> Rest of the code
'
.Tag = rst![ID]
'
'~~> Rest of the code
'
End With
As mentioned Siddharth Rout:
'creating checkboxes
If Not rst.EOF And Not rst.BOF Then
rst.MoveFirst
i = 0
Do
With MultiPage1.Pages(1).Controls.Add("Forms.Checkbox.1", "Checkbox" & i)
.Top = yPos
.Left = 7
.Caption = rst![name]
.Width = 450
.Height = 24
.WordWrap = True
.Value = False
yPos = yPos + 17
.Tag = rst![ID]
i = i + 1
rst.MoveNext
End With
Loop Until rst.EOF
End If
rst.Close
cnn.Close
Set rst = Nothing
Set cnn = Nothing
I am using Visual Basic in Visual Studio 2017. I am trying to create buttons from a text file. If a text file contains words like
Test1
Test2
Test3
etc it should create 3 buttons using those names.
Dim path As String = "c:\words.txt"
Dim readText() As String = File.ReadAllLines(path)
Dim s As String
Dim button As New System.Windows.Forms.Button()
Dim buttonTop As Integer = 100
For Each s In readText
Dim Location As New Point(100, (buttonTop + 20))
button.Location = Location
button.Text = s
button.Width = 100
Me.Controls.Add(button)
buttonTop += 20
button.Visible = True
Next
This code creates the buttons but are not saved. As the loop goes it creates them and they disappear from the form leaving just the last one at the end of the loop.
Any guidelines will be appreciated. Thanks.
Correct Answer. Thanks
Dim path As String = "c:\words.txt"
Dim readText() As String = File.ReadAllLines(path)
Dim s As String
Dim buttonTop As Integer = 20
For Each s In readText
Dim button As New System.Windows.Forms.Button()
Dim Location As New Point(100, (buttonTop + 30))
button.Location = Location
Button.Text = s
button.Width = 100
button.Height = 30
Me.Controls.Add(Button)
buttonTop += 30
button.Visible = True
Next
I need to loop through an array of user controls that were programmatically created.
Where My problem is later I need to loop through the array of user controls created and use the controls of the user control
My sudo code. The line I cannot figure out is
MyCtrl.tbQtyM.Text = Format(60 / Val(MyCtrl.tbMPU.Text) / 55 * NumEmployees, "0.00")
Dim MyProds As New MyMPUProduct
For iLoop2 = 1 To Val(sender.Text)
MyProds = New MyMPUProduct
Me.TabControl1.SelectedTab.Controls.Add(MyProds)
With MyProds
.Name = "MyProd" & iLoop2
.Location = New Point(6, MyProdSpace)
.VerifyTMPUProductsTblApt()
.TMPUProductsBindingSource.Filter = "ID = '-1'"
.tbMix.Text = "0"
.Label1.Text = iLoop2
End With
Next
Dim CtrlName As String
For i = 1 To NumProds
CtrlName = "MyProd" & i
For Each MyCtrl As Control In Me.TabControl1.SelectedTab.Controls
If TypeOf MyCtrl Is MyMPUProduct Then
MyCtrl.tbQtyM.Text = Format(60 / Val(MyCtrl.tbMPU.Text) / 55 * NumEmployees, "0.00")
End If
Next
Next
I need to create an edit control that takes each line, as entered, and goes off and does an action according to what was entered. I don't want the user to be able to delete what they typed into the box via their mouse and the delete key. It would look something like this:
Power On (user entered this)
Power: On Level:50 (what the power on command returned)
Laser On (user entered this )
Laser: On Power:60 ( what the command returned)
So I don't want them to go back and delete the lines already entered, they can just keep appending items and sending off these commands. Any ideas on how to accomplish this? Thanks.
I think your best bet would be creating a hybrid UserControl consisting of 2 Textbox's one which is readonly the other being writable. Enter your data in the one, append it to the other when the enter key is pressed, then append the response. Since you haven't stated a programming language here is an example in vb.net.
Public Class UserControl1
Private Sub TextBox2_KeyDown(sender As Object, e As KeyEventArgs) Handles TextBox2.KeyDown
If e.KeyCode = Keys.Enter Then
ScrollToEnd(TextBox1)
TextBox1.Text += TextBox2.Text + vbCrLf
TextBox1.Text += GetResponse(TextBox2.Text) + vbCrLf
TextBox2.Text = ""
ScrollToEnd(TextBox1)
e.SuppressKeyPress = True
End If
End Sub
Private Sub ScrollToEnd(tb As TextBox)
tb.SelectionStart = tb.TextLength
tb.ScrollToCaret()
End Sub
Private Function GetResponse(command As String) As String
Select Case command
Case "Power On"
Return "On Level: 50"
Case "Laser On"
Return "Laser: On Power:60"
Case Else
Return "I do not understand"
End Select
End Function
End Class
UserControl1.Designer.VB's InitializeComponent Method (I am only putting this in so you can see the properties of my Controls)
Private Sub InitializeComponent()
Me.TextBox1 = New System.Windows.Forms.TextBox()
Me.TextBox2 = New System.Windows.Forms.TextBox()
Me.TableLayoutPanel1 = New System.Windows.Forms.TableLayoutPanel()
Me.TableLayoutPanel1.SuspendLayout()
Me.SuspendLayout()
'
'TextBox1
'
Me.TextBox1.BackColor = System.Drawing.Color.Black
Me.TextBox1.BorderStyle = System.Windows.Forms.BorderStyle.None
Me.TextBox1.Dock = System.Windows.Forms.DockStyle.Fill
Me.TextBox1.ForeColor = System.Drawing.Color.Lime
Me.TextBox1.Location = New System.Drawing.Point(3, 3)
Me.TextBox1.Multiline = True
Me.TextBox1.Name = "TextBox1"
Me.TextBox1.ReadOnly = True
Me.TextBox1.Size = New System.Drawing.Size(253, 181)
Me.TextBox1.TabIndex = 0
Me.TextBox1.TabStop = False
'
'TextBox2
'
Me.TextBox2.BackColor = System.Drawing.Color.Black
Me.TextBox2.BorderStyle = System.Windows.Forms.BorderStyle.None
Me.TextBox2.Dock = System.Windows.Forms.DockStyle.Fill
Me.TextBox2.ForeColor = System.Drawing.Color.Lime
Me.TextBox2.Location = New System.Drawing.Point(3, 190)
Me.TextBox2.Name = "TextBox2"
Me.TextBox2.Size = New System.Drawing.Size(253, 17)
Me.TextBox2.TabIndex = 1
'
'TableLayoutPanel1
'
Me.TableLayoutPanel1.BackColor = System.Drawing.Color.Black
Me.TableLayoutPanel1.ColumnCount = 1
Me.TableLayoutPanel1.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50.0!))
Me.TableLayoutPanel1.Controls.Add(Me.TextBox1, 0, 0)
Me.TableLayoutPanel1.Controls.Add(Me.TextBox2, 0, 1)
Me.TableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill
Me.TableLayoutPanel1.Location = New System.Drawing.Point(0, 0)
Me.TableLayoutPanel1.Name = "TableLayoutPanel1"
Me.TableLayoutPanel1.RowCount = 2
Me.TableLayoutPanel1.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 89.09953!))
Me.TableLayoutPanel1.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 10.90047!))
Me.TableLayoutPanel1.Size = New System.Drawing.Size(259, 211)
Me.TableLayoutPanel1.TabIndex = 2
'
'UserControl1
'
Me.AutoScaleDimensions = New System.Drawing.SizeF(7.0!, 16.0!)
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
Me.Controls.Add(Me.TableLayoutPanel1)
Me.Name = "UserControl1"
Me.Size = New System.Drawing.Size(259, 211)
Me.TableLayoutPanel1.ResumeLayout(False)
Me.TableLayoutPanel1.PerformLayout()
Me.ResumeLayout(False)
End Sub