Удалить динамические элементы управления внутри панели с динамическими кнопками - PullRequest
1 голос
/ 02 июля 2019

Мой код динамически создает метку с белым фоном внутри панели одним нажатием кнопки. Над каждой динамически создаваемой меткой находится красная кнопка «X», с помощью которой можно удалить каждую метку.
Все работает, за исключением того, что я могу удалить только последний созданный ярлык. Я хотел бы, чтобы код удалял каждый ярлык по одному.

Я знаю, 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 Ответ

1 голос
/ 02 июля 2019

Проблема в том, что вы воссоздаете List(Of Control) каждый раз, когда создается новый ярлык, поэтому список будет содержать только последний добавленный ярлык.
При попытке удалитьодин из ярлыков, вы перебираете всю коллекцию.Если List(Of Control) правильно поддерживается, вы удалите все элементы управления.

Кстати, не используйте это:

Panel1.Controls.Remove(c)

Просто позвоните [Control].Dispose(), вы избавитесь от объекта, и он также удалит его из коллекции контейнеров.

Другая, более тонкая проблема заключается в способе размещения элементов управления на контейнере Panel: вам будет трудно переместить один из элементов управления на прежнее место (при необходимости), когдаконтроль снят.Используя этот счетчик, вы только увеличиваете позицию Location.X.

Я предлагаю добавить FlowLayoutPanel на панель, которую вы используете для размещения своих элементов управления.Поместите его в Panel, установите для его свойства Dock значение DockStyle.Fill, затем добавьте к нему элементы управления, и он позаботится об их размещении.Для правильной работы Button необходимо, чтобы было в родительском с меткой.
Вы также можете создать UserControl вместо использования пары стандартных элементов управления.

Здесь свойство Tag кнопки используется для ссылки на метку, которой оно принадлежит.
При нажатии кнопки объект sender будет кнопкой, которая была поднятасобытие, вам просто нужно привести sender к Button (или Control), чтобы получить доступ к его свойствам.
Свойство Tag используется для удаленияrelated 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...