使用动态按钮删除面板内的动态控件

时间:2019-07-02 01:06:58

标签: vb.net winforms

我的代码通过单击一个按钮,动态地在面板内部生成一个带有白色背景的Label。每个动态生成的Label的顶部都有一个红色的“ X”按钮,可用于删除每个Label。
一切正常,除了我只能删除创建的最后一个Label。我希望代码一次删除一个标签。

我知道panel1.controls.clear()将删除面板中的所有内容,但是我想使用标签上产生的删除按钮分别删除每个标签。

Public Class Form1
    Dim counter As Integer = 0
    Dim MyControls As List(Of Control)

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        MyControls = New List(Of Control)
        Dim lblBg As New Label 
        Dim btnDelete As New Button

        lblBg.Size = New Size(230, 200)
        lblBg.Location = New Point(counter * 240, 10)
        lblBg.BackColor = Color.White
        lblBg.ForeColor = Color.Black

        btnDelete.Name = "btn" & counter
        btnDelete.Size = New Size(25, 25)
        btnDelete.Location = New Point(counter * 240, 10)
        btnDelete.BackColor = Color.White
        btnDelete.ForeColor = Color.Red
        btnDelete.Font = New System.Drawing.Font("Arial", 10.0!, System.Drawing.FontStyle.Bold)
        btnDelete.Text = "x"
        btnDelete.FlatAppearance.BorderSize = 0
        btnDelete.FlatStyle = FlatStyle.Flat
        AddHandler btnDelete.Click, AddressOf ButtonClick

        Panel1.Controls.Add(btnDelete)
        MyControls.Add(btnDelete)
        Panel1.Controls.Add(lblBg)
        MyControls.Add(lblBg)
        counter += 1
    End Sub

    Private Sub ButtonClick(sender As Object, e As EventArgs)
        counter = 0
        For Each c As Control In MyControls
            Panel1.Controls.Remove(c)
            c.Dispose()
        Next
    End Sub
End Class

1 个答案:

答案 0 :(得分:1)

问题在于,每次创建新标签时,您都要重新创建 List(Of Control) ,因此列表将仅包含您添加的最后一个标签。
尝试删除其中一个标签时,您正在迭代整个集合。如果List(Of Control)得到正确维护,则将删除所有控件。

顺便说一句,不要使用此:

Panel1.Controls.Remove(c)

只需调用[Control].Dispose(),您就可以处理该对象,这还将把它从容器的集合中删除。

另一个更微妙的问题是将控件放置在面板容器上的方式:在删除控件时,您将很难将控件之一重新放置到先前的位置(如果需要) 。使用该计数器,您只需增加Location.X的位置。

我建议在用于放置控件的面板中添加FlowLayoutPanel。将其放置在面板中,将其Dock属性设置为 DockStyle.Fill ,然后向其中添加控件,它将为您处理它们的放置。该按钮需要与标签 parented 配合才能正常工作。
您也可以创建UserControl而不是使用几个标准控件。

在这里,Button的Tag属性用于引用它所属的Label。
单击按钮后, sender 对象将成为引发事件的按钮,您只需将 sender 投射到 Button (或Control)访问其属性。
Tag属性用于处理相关的Label。
事件处理程序还需要未注册

注意:该代码中的FlowLayoutPanel被命名为 flp1

Private Sub btnAddLabel_Click(sender As Object, e As EventArgs) Handles btnAddLabel.Click

    Dim lblBg As New Label() With {
        .BackColor = Color.White,
        .ForeColor = Color.Black,
        .Size = New Size(230, 200)
    }

    Dim btnDelete As New Button() With {
        .BackColor = Color.White,
        .ForeColor = Color.Red,
        .Font = New Font("Arial", 10.0!, FontStyle.Bold),
        .Location = New Point(0, 0),
        .Parent = lblBg,
        .Size = New Size(25, 25),
        .Tag = lblBg,
        .Text = "x"
    }
    btnDelete.FlatAppearance.BorderSize = 0
    btnDelete.FlatStyle = FlatStyle.Flat
    AddHandler btnDelete.Click, AddressOf ButtonDeleteClick
    flp1.Controls.Add(lblBg)
End Sub

Private Sub ButtonDeleteClick(sender As Object, e As EventArgs)
    Dim ctrl As Control = DirectCast(sender, Control)
    DirectCast(ctrl.Tag, Control).Dispose()
    RemoveHandler ctrl.Click, AddressOf ButtonDeleteClick
    ctrl.Dispose()
End Sub