I have a form that I display exclusively with the ShowDialog
method. In the Form_Shown
event, I dynamically create a set of labels and text boxes based on a public variable set in the form making the call.
I understand that the form is not closed or destroyed but simply hidden between calls, and as such I added code at the top of my Form_Shown
event to clear out any controls from a previous call, but the controls aren't being removed. I have tried ctrl.Dispose
(as in the code below) and Me.Controls.Remove(ctrl)
. Neither produces an error, but the Textboxes are not removed and new ones are created over them. (For some reason,
This is the first time I've dynamically created/removed controls in .NET, so it's possible my yearning for VB6's control arrays have something to do with the error.
The form builds itself based on the calling form's public ListView variable. The calling form makes certain this variable is not nothing and that items are selected if and only if the user is editing an existing row.
Public Class frmTableEdit
Private isNew As Boolean
Private inputText() As TextBox
Private Sub FormTableEdit_Shown(sender As Object, e As EventArgs) Handles MyBase.Shown
For Each ctrl As Control In Me.Controls
If TypeOf (ctrl) Is TextBox Or TypeOf (ctrl) Is Label Then
ctrl.Dispose()
End If
Next
With frmKioskData.TBLobj
Dim fieldCount As Integer = .Columns.Count - 1
isNew = .SelectedIndices.Count = 0
'(code setting size of form and location of OK/Cancel buttons is here)
ReDim inputText(fieldCount)
For i As Integer = 0 To fieldCount
Dim lbl As New Label, txt As New TextBox
inputText(i) = txt
Me.Controls.Add(lbl)
Me.Controls.Add(txt)
'(code setting size and and position of lbl & txt is here)
'lbl.Tag = i (I commented these lines out because I never used the
'txt.Tag = i Tag property, but can if a solution calls for it.)
lbl.Text = .Columns(i).Text
If isNew Then
txt.Text = ""
Else
txt.Text = .Items(.SelectedIndices(0)).SubItems(i).Text
End If
Next
End With
End Sub
End Class
If @Plutonix's suggestion in the comment above does not quite work for you, I think it would be easiest and make more sense to dispose of the form after calling ShowDialog, and then when you need to show that form you create a new instance with a parameter that tells it what dynamic controls to load.
So you'd have a New method in frmTableEdit that uses this parameter:
Public Sub New(ByVal fieldCount As Integer)
InitializeComponent()
fieldCount = fieldCount 'Where fieldCount is a class variable
End Sub
And when you call this form from frmKioskData, you can do so like this:
Dim newTableEdit As New frmTableEdit(Me.TBLobj.Columns.Count - 1)
newTableEdit.ShowDialog()
newTableEdit.Dispose()
Then the code in your frmEditTable's Shown event just simply has to add the controls accordingly, without the need to remove old ones:
ReDim inputText(fieldCount)
For i As Integer = 0 To fieldCount
Dim lbl As New Label, txt As New TextBox
inputText(i) = txt
Me.Controls.Add(lbl)
Me.Controls.Add(txt)
'(code setting size and and position of lbl & txt is here)
'lbl.Tag = i (I commented these lines out because I never used the
'txt.Tag = i Tag property, but can if a solution calls for it.)
lbl.Text = .Columns(i).Text
If isNew Then
txt.Text = ""
Else
txt.Text = .Items(.SelectedIndices(0)).SubItems(i).Text
End If
Next
How you get the isNew value is up to you - you can add that as a second parameter to the form's New, or get it the same way you are now...w/e. If it were me I'd normally add that as another New parameter.