I'm trying to dynamically adding and removing objects in my form. I'm stuck on how to get the unique identifier of which object to remove.
'Collection of controls
For Each ctl In Me.Controls
'Get control type
If TypeOf ctl Is Label Then
'Get control name/index id/text or any property of current ctl
'How do I continue from here?
'Me.Controls.Remove(ctl)
End If
Next
Thanks in advance for solutions/suggestions.
If it's alright, I would like to know the explanation of the solutions.
If you guys need to know how I added objects dynamically, here it is:
For i = 1 To Spots
Dim newLabel As New Label
Dim newLoc As Integer = iLoc + (i * 30)
With newLabel
.Name = "lblSpot" & i
.Text = "Spot " & i
.Size = New Size(100, 20)
.Location = New Point(3, newLoc)
End With
AddHandler Me.Load, AddressOf frmParking_Load
Me.Controls.Add(newLabel)
Next
You can cast ctl to Label and then use .Name to find the controls to delete
Using For Each when change collection is not recommended, so here is the code you want
Dim i = 0
While i < Me.Controls.Count
Dim c = Me.Controls(i)
If TypeOf c Is Label Then
Dim Lbl As Label = CType(c, Label)
If Lbl.Name.Contains("lblSpot") Then
Me.Controls.Remove(c)
End If
End If
End While
Related
This is one of the form, all the usercontrol value in this form will store in My.Settings
I have another form with a FlowLayoutPanel, everytime when the application start,
if Active checked then it will add a Button with discount value to the FlowLayoutPanel.
Should I add those usercontrol to a list and then loop through the list? Or what is the best way to solve this kind of problem?
UPDATED
How can I add multiple item to list in 1 code? I getting this error when system run to line 5
An exception of type 'System.NullReferenceException' occurred in XXX.exe but was not handled in user code
Additional information: Object reference not set to an instance of an object.
Public Sub RefreshDiscount(ByRef ref As scr_mainDiscount)
Dim li_disName As New List(Of TextBox)
Dim li_disValue As New List(Of TextBox)
Dim li_disType As New List(Of ComboBox)
Dim li_active As New List(Of CheckBox)
Dim tb_disName As TextBox() = {ref.tb_name1, ref.tb_name2, ref.tb_name3, ref.tb_name4, ref.tb_name5, ref.tb_name6, ref.tb_name7, ref.tb_name8, ref.tb_name9, ref.tb_name10}
Dim tb_disValue As TextBox() = {ref.tb_value1, ref.tb_value2, ref.tb_value3, ref.tb_value4, ref.tb_value5, ref.tb_value6, ref.tb_value7, ref.tb_value8, ref.tb_value9, ref.tb_value10}
Dim cb_disType As ComboBox() = {ref.cb_type1, ref.cb_type2, ref.cb_type3, ref.cb_type4, ref.cb_type5, ref.cb_type6, ref.cb_type7, ref.cb_type8, ref.cb_type9, ref.cb_type10}
Dim chkb_active As CheckBox() = {ref.CheckBox1, ref.CheckBox2, ref.CheckBox3, ref.CheckBox4, ref.CheckBox5, ref.CheckBox6, ref.CheckBox7, ref.CheckBox8, ref.CheckBox9, ref.CheckBox10}
li_disName.AddRange(tb_disName)
li_disValue.AddRange(tb_disValue)
li_disType.AddRange(cb_disType)
li_active.AddRange(chkb_active)
For index As Integer = 0 To li_active.Count - 1
If li_active(index).Checked = False Then
li_disName.RemoveAt(index)
li_disValue.RemoveAt(index)
li_disType.RemoveAt(index)
li_active.RemoveAt(index)
Else
Dim btn As New ctrl_DiscountButton
With btn
.Text = li_disName(index).Text
.Price = li_disValue(index).Text
.Type = li_disType(index).Text
End With
scr_sales.flp_discount.Controls.Add(btn)
End If
Next
li_disName.Clear()
li_disValue.Clear()
li_disType.Clear()
li_active.Clear()
End Sub
Here's a simple example showing how to find CheckBox1 thru CheckBox10, "by name", using the "searchAllChildren" option of Controls.Find():
For i As Integer = 1 To 10
Dim ctlName As String = "CheckBox" & i
Dim matches() As Control = Me.Controls.Find(ctlName, True)
If matches.Length > 0 AndAlso TypeOf matches(0) Is CheckBox Then
Dim cb As CheckBox = DirectCast(matches(0), CheckBox)
' do something with "cb"
If cb.Checked Then
' ... code ...
' possibly use code just like this to find the matching discount value control?
End If
End If
Next
I am creating few text boxes in windows forms dynamically and at some point I dispose these
Dim tb1 As New TextBox 'new textbox
tb1.Name = "dtba" 'setname
tb1.Location = New Point(stx, sty) 'location of textbox
tb1.Text = arl(0) 'assigning text
tb1.Width = 80 'setting width
tb1.TabStop = False 'no tabstop
tb1.Enabled = False 'disabled
Me.Controls.Add(tb1) 'add to form
'Repeating same code for few more text boxes
Dim tb2 As New TextBox
tb2.Name = "dtbb"
tb2.Location = New Point(stx + 80, sty)
tb2.Text = arl(1)
tb2.Width = 175
tb2.TabStop = False
tb2.Enabled = False
Me.Controls.Add(tb2)
Dim tb3 As New TextBox
tb3.Name = "dtbc"
tb3.Location = New Point(stx + 255, sty)
tb3.Text = arl(2)
tb3.Width = 125
tb3.TabStop = False
tb3.Enabled = False
Me.Controls.Add(tb3)
Dim tb4 As New TextBox
tb4.Name = "dtbd"
tb4.Location = New Point(stx + 380, sty)
tb4.Text = arl(3)
tb4.Width = 100
tb4.TabStop = False
tb4.Enabled = False
Me.Controls.Add(tb4)
Problem occurring when I try to delete these text boxes. Code is
For Each cControl In Me.Controls
If (TypeOf cControl Is TextBox) Then
Dim txt As TextBox = CType(cControl, TextBox)
If txt.Name.Contains("dtb") Then
txt.Dispose()
End If
End If
Next cControl
Here the text boxes named dtba and dtbc getting deleted. But dtbb and dtbd are not getting deleted. Any help ?
You are editing the collection whilst looping over it. Try something like this instead:
Dim l As New List(Of Control)
For Each cControl In Me.Controls
If (TypeOf cControl Is TextBox) Then
Dim txt As TextBox = CType(cControl, TextBox)
If txt.Name.Contains("dtb") Then
l.Add(cControl)
End If
End If
Next cControl
For Each c As Control In l
c.Dispose()
Next
Instead utilize this:
For Each cControl In Me.Controls
If (TypeOf cControl Is TextBox) Then
Dim txt As TextBox = CType(cControl, TextBox)
If txt.Name.Contains("dtb") Then
txt.Dispose()
End If
End If
Next cControl
Do this:
Again:
For Each cControl In Me.Controls
If (TypeOf cControl Is TextBox) Then
Dim txt As TextBox = CType(cControl, TextBox)
If txt.Name.Contains("dtb") Then
Me.Controls.Remove(txt)
GoTo again
End If
End If
Next
The problem is related to INDEX of FOR EACH, that loss the pointer when the controls is deleted. You must repeat the operation to ensure a new index.
I have 10 buttons namely button01, button02 ... button10. What I want is how to manipulate it.
For x=1 to 10
button(x).text = "blah" 'from database...or something
next
I need to do this because I have 10 buttons or more and I want to manipulate it through initialization. So that I don't do it manually one by one. I don't know how to do this. I'm still new in .NET.
You should not need to do it in this error-prone way just to save you some lines of code. But if you really want....
You can use a Panel or another container control that groups the related controls logically. Then use MyPanel.Controls.OfType(Of Button)() to filter and find all the buttons there.
For Each btn As Button In MyPanel.Controls.OfType(Of Button)()
btn.Text = "blah" 'from database...or something
Next
Another way is to put them all in an array or other collection type like List(Of Button) first and loop over them afterwards:
Dim myButtons = {button1, button2, button3, button4, button5, button6}
For Each btn In myButtons
btn.Text = "blah" 'from database...or something
Next
Last you could use ControlCollection.Find to find controls with a given string for its name:
For i As Int32 = 1 To 10
Dim btns = Me.Controls.Find("button" & i, True)
If btns.Length > 0 Then
btns(0).Text = "blah" 'from database...or something
End If
Next
Simply:
For i As Integer = 1 To 10
Me.Controls("button" & i.ToString("00")).Text = "blah"
Next
You have to iterate through the parent container of these buttons.
Say you are holding these controls inside a panel called PnlTest, then you have to do it like this:
For Each xControls As Control In PnlTest.Controls
If TypeOf xControls Is Button Then
xControls.Text = "blah" 'from database...or something
End If
Next
You could try using the method FindControl as such from the WebControl:
For x=1 to 10
FindControl("button" & if(x < 10, "0" & x, x) = "blah" 'from database...or something
next
EDIT: I primarily use C#, not VB, so it may need some alteration. However, the approach is the same I would believe.
zeroyevi cubosoft.cl -- DevExpress -- la clave esta (bar.button.item) en Me.RibbonControl.Items("NAME_BUTTON" ).Enabled = True or false
Private Sub GetSearchPerfilModulosBotones(ByVal _id_perfil As String)
Dim dt As New DataTable
Dim _act_btns As Boolean
Dim _name_btns As String
Dim _name_module As String = Me.Name.ToString()
Try
Dim _ControlDatosSistema As New ControlDatosSistema()
With _ControlDatosSistema
dt = .GetSearchPerfilModulosBotones(_id_perfil, _name_module )'SQL QUERY
If (dt.Rows.Count >= 1) Then
For Each row As DataRow In dt.Rows
_act_btns = row("ACT_BTNS") 'BOTONES PERFIL True or False
_name_btns = row("NAME_BTNS").ToString()'NOMBRE BOTONES TABLA
Me.RibbonControl.Items(_name_btns ).Enabled = _act_btns
Next
End If
End With
_ControlDatosSistema = Nothing
dt.Dispose()
Catch ex As Exception
End Try
End Sub
I want to be able to reveal and then populate a certain number of labels. The inefficient way would be to SELECT CASE on the number of labels required and then populate these in turn. I am looking for something like this:
For i = 1 to RequiredNumOfLabels
Label & i.visible = true
Label & i.text = DataTable.Rows(i).Item(2)
Next
Thank you.
EDIT:
For i = 1 To NumberOfItems
Dim lbl = Controls("lbl" & i)
lbl.Visible = True
lbl.Text = CStr(DataTable.Rows(i).Item(2))
Next
I think the line
Dim lbl = Controls("lbl" & i)
is the problem as after the line is executed, lbl still equals nothing.
The reasoning behind it is that I was trying to create an invoice generator in vb.net and I was hoping that this would be a simple way to do it - count the amount of items in the order, populate the labels with the names of the items, reveal that many labels.
If your label controls are really in order like that, you can try just referencing them from a list:
Dim myLabels As New List(Of Label)
myLabels.Add(Label1)
myLabels.Add(Label2)
Then just update them:
For i as Integer = 1 to myLabels.Count
myLabels(i - 1).Visible = True
myLabels(i - 1).Text = DataTable.Rows(i).Item(2).ToString
Next
You can get controls by name through the forms Controls property
For i = 1 To RequiredNumOfLabels
Dim lbl = TryCast(Controls("Label" & i), Label)
If lbl IsNot Nothing Then
lbl.Visible = True
lbl.Text = CStr(DataTable.Rows(i).Item(2))
End If
Next
Since you get an object of type Control, you have to cast it to Label.
UPDATE
It seems that you only use properties that are defined in Control anyway. Therfore you can simplify the code to
For i = 1 To RequiredNumOfLabels
Dim lbl = Controls("Label" & i)
lbl.Visible = True
lbl.Text = CStr(DataTable.Rows(i).Item(2))
Next
I'm trying to create a list of labels and textboxes. No errors but they aren't rendering on the form. I have confirmed my loop have values
Private Sub AddLabels_Load(sender As Object, e As EventArgs) Handles MyBase.Load
'MsgBox(strNumberOfLabels + " " + strOrderNum)
TableLayoutPanel1.AutoSize = True
TableLayoutPanel1.Visible = False
TableLayoutPanel1.SuspendLayout()
For i As Integer = 0 To strNumberOfLabels
'MsgBox(i)
Dim txtBox As New TextBox
Dim txtLabel As New Label
txtLabel.Text = "Label " + i
txtBox.Name = "txt" + i
TableLayoutPanel1.Controls.Add(txtLabel)
txtLabel.Show()
txtBox.Show()
TableLayoutPanel1.ResumeLayout()
TableLayoutPanel1.Visible = True
Next
End Sub
Try using the other Add overload, which specifies which column and row the control should go into:
Dim txtLabel As New Label
txtLabel.Text = "Label" + i.ToString
'\\ TableLayoutPanel1.Controls.Add(txtLabel)
TableLayoutPanel1.Controls.Add(txtLabel, 0, 0)
This is not necessary:
'\\ txtLabel.Show()
This should be moved outside of the loop:
Next
TableLayoutPanel1.ResumeLayout()
'\\ TableLayoutPanel1.Visible = True
The txtBox control is never being added to the TableLayoutPanel control or the form.
I don't think it's necessary to make your TableLayoutPanel visible or invisible during the OnLoad procedure, the form isn't visible yet.
The only other thing to confirm is the value of strNumberOfLabels. I'm suspecting it's zero.