Мой код динамически создает метку с белым фоном внутри панели одним нажатием кнопки. Над каждой динамически созданной меткой находится красная кнопка «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
Назначьте Label, который вы только что создали, свойству Tag только что созданного Button. В обработчике событий Click получите Button из параметра sender, получите Label из Tag из Button, а затем Remove их обоих из Panel. Не забудьте удалить обработчик события из файла Button.
Кроме того, вам действительно следует использовать TableLayoutPanel или FlowLayoutPanel для автоматического позиционирования элементов управления. Кроме того, вам следует подумать о разработке собственного пользовательского элемента управления, содержащего Label и Button. Таким образом, весь блок будет автономным.





Проблема в том, что вы воссоздаете List(Of Control) каждый раз, когда создается новая метка, поэтому список будет содержать только последнюю добавленную вами метку.
При попытке удалить одну из меток вы перебираете всю коллекцию. Если бы List(Of Control) обслуживался должным образом, вы удалили бы все элементы управления.
Кстати, не используйте это:
Panel1.Controls.Remove(c)
Просто вызовите [Control].Dispose(), вы избавитесь от объекта, и это также удалит его из коллекции контейнеров.
Другая, более тонкая проблема заключается в том, как вы позиционируете элементы управления в контейнере Panel: вам будет трудно переместить один из элементов управления на прежнее место (при необходимости), когда элемент управления будет удален. Используя этот счетчик, вы только увеличиваете позицию Location.X.
Я предлагаю добавить FlowLayoutPanel в панель, которую вы используете для размещения элементов управления. Поместите его внутрь панели, установите для его свойства Док значение DockStyle.Fill, затем добавьте в него свои элементы управления, он позаботится об их размещении за вас. Кнопка должна быть родитель с меткой, чтобы работать правильно.
Вы также можете создать UserControl вместо пары стандартных элементов управления.
Здесь свойство Tag кнопки используется для ссылки на метку, которой она принадлежит.
Когда кнопка нажата, объект sender будет кнопкой, вызвавшей событие, вам просто нужно привести sender к Button (или Control), чтобы получить доступ к ее свойствам.
Свойство Tag используется для удаления связанной метки.
Обработчик события также должен быть незарегистрированный.
Примечание: в этом коде 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
вау спасибо большое за подробное объяснение. Мне эта информация очень пригодилась!
Будем признательны за любую помощь опытного программиста VB!