Question Dynamic controls disposal. Only 50% of controls removed. Source provided.

JCBDan

New member
Joined
Sep 16, 2010
Messages
2
Programming Experience
1-3
Hello all,
I am new to this board first thanks for your time,
I have a query about dynamically added controls to a form. I have a series of buttons which are created and added at run time. I have a two drop down lists and two buttons which are created at design time. Button 1 creates a series of buttons called "Test 1.. x" based upon the selection of the two drop down lists. This works fine and am happy with the logic.
However.... Button two should remove all the dynamically created buttons from the form.
This does not happen. What does happen is that 50% of the buttons are removed starting with the first one. WHen checking the loop it only enters the loop half the amount of times that there are buttons. Very strange. When the loop is run repeatability it will remove all controls. Why will my logic not remove all the dynamically created controls at once? What is wrong with my logic?

Thank you for your time.


I attach two code snippets and the .net file for your consideration.

Button method which creates the dynamically created buttons from the two drop down lists and adds to form
---------------------------------------------------------------

VB.NET:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim Count As Integer
        Dim MaxHours As Integer

        MaxHours = hours.SelectedItem * years.SelectedItem

        Count = 0

        While Count < MaxHours

            Dim btnYes As System.Windows.Forms.Button
            ' Create control
            btnYes = New System.Windows.Forms.Button()
            ' Set button properties
            btnYes.Name = "Test" + releaseNumber.ToString
            btnYes.Size = New System.Drawing.Size(70, 30)
            btnYes.Location = New System.Drawing.Point(0, Location1)
            btnYes.Text = Count
            ' add to the parent form's controls collection
            Me.Controls.Add(btnYes)
            AddHandler btnYes.Click, AddressOf Button1_Click
            Location1 = Location1 + 30
            Count += 500


        End While


Button method which removes only 50% of buttons. (I want to remove all)
---------------------------------------------------------

VB.NET:
    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        Dim i As Integer = 0

        For Each ctrl As Control In Me.Controls
            i += 1

            If (ctrl.Name.Substring(0, 4) = "Test") Then
                CType(ctrl, Button).Dispose()
            End If

        Next
    End Sub
 

Attachments

  • Dynamic Controls Test.zip
    14.3 KB · Views: 18
Last edited by a moderator:
Disposing the control also removes it from the parent collection, so you are in effect modifying the collection while enumerating it, never a good idea. You could do a For-Next loop Step-1 and access the control collection by that index.

Depending on layout you could also do a Controls.Clear, or if there are other controls that should not be removed you could use a dedicated control group (Panel, GroupBox, or other container control) for the dynamic controls and just Clear that. For example with a FlowLayoutPanel the controls are positioned automatically. If you do Clear the controls are not disposed, which is necessary, so you could for example handle the ControlRemoved event and dispose them from there (e.Control.Dispose).
 
Ahh i see, as i'm looping through, i'm removing controls and hence the total size of the list of controls while i'm mid cycle. So the list reduces in size while the pointer is still at the same position. It makes perfect sense. Thankyou.
 
One more thing, when you use AddHandler you assign a reference to that control. Later when control is disposed you also need to use RemoveHandler to allow the object to be garbage collected, if not it will still occupy the memory in it's disposed state.
 

Latest posts

Back
Top