Как сделать eventlistener кнопки внутри ещё одного eventlistener'a кнопки?
Дело такое. Пытаюсь написать простейшую тудушку в Windows Forms на C#, и столкнулся с проблемой.
Есть условная кнопка "создать", которая создает с каждым нажатием новый лейбл с текстом внутри, который был введён пользователем в текстбокс. А также, вместе с лейблом, слева от него создается кнопка, которая предназначена для удаления этого лейбла при нажатии.
Ну и, проблема в том, что я никак не могу реализовать удаление лейбла. Да что удаление, даже удаление его текста.
Так как внутри метода нельзя сделать ещё один метод, это не прокатит. А у класса Button нет своего собственного метода, который проверяет нажата ли кнопка, а потом делает заданные инструкции.
Я пытался сделать отдельный метод, но потом понял, что программа тупо не сможет понять, о какой кнопке я вообще говорю, так как кнопка создается только при нажатии пользователем уже после компиляции программы, поэтому она просто не может знать об этой кнопке.
Что делать? Как реализовать удаление лейбла?
Буду очень благодарен за любую помощь!
using System;
using System.Drawing;
using System.Windows.Forms;
namespace TODO
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
int lCount = 0;
private void button1_Click(object sender, EventArgs e)
{
lCount++;
Label lbl = new Label();
Button button = new Button();
lbl.Text = "Text text text text";
button.Text = "X";
lbl.Location = new Point(40, 4 + 30 * (lCount - 1));
lbl.AutoSize = true;
button.Location = new Point(10, 30 * (lCount - 1));
button.Size = new Size(20, 20);
this.Controls.Add(lbl);
this.Controls.Add(button);
}
}
}
Ответы (2 шт):
Первое, что в голову пришло - удаление по имени. Удаляет и Label и Button, который был нажат. Я уверен, что есть более изящное решение.
int lCount = 0;
private void button1_Click(object sender, EventArgs e)
{
lCount++;
Label lbl = new Label();
Button button = new Button();
button.Name = "b_" + lCount.ToString();
lbl.Name = "l_" + lCount.ToString();
lbl.Text = "Text text text text";
button.Text = "X";
lbl.Location = new Point(40, 4 + 30 * (lCount - 1));
lbl.AutoSize = true;
button.Location = new Point(10, 30 * (lCount - 1));
button.Size = new Size(20, 20);
button.Click += new EventHandler(butLabel_Click);
this.Controls.Add(lbl);
this.Controls.Add(button);
}
private void butLabel_Click(object sender, EventArgs e)
{
Button btnForDelete = (Button)sender;
string lblForDeleteName = "l_" + btnForDelete.Name.Split('_')[1];
foreach (Control item in this.Controls.OfType<Control>().ToList())
{
if (item.Name == lblForDeleteName)
this.Controls.Remove(item);
this.Controls.Remove(btnForDelete);
}
}
public class DeletableLabelItem : UserControl
{
string _Text = "Text";
public override string Text { get => _Text; set { _Text = value; SetText(value); } }
public Button Button { get; private set; } = new Button() { Text = "X", Location = new Point(1, 1), Size = new Size(18, 18) };
public Label Label { get; private set; } = new Label() { Text = "Text", Location = new Point(21, 1), Size = new Size(78, 18) };
public int Index => ContainerParent?.GetIndex(this) ?? -1;
protected DeletableLabelItemContainer ContainerParent { get; set; }
protected void SetText(string text) => Label.Text = text;
public DeletableLabelItem(string Text, Point Location, DeletableLabelItemContainer Parent = null)
{
this.Size = new Size(100, 20);
Controls.Add(Button);
Controls.Add(Label);
this.Text = Text;
this.Location = Location;
ContainerParent = Parent;
this.Button.Click += Delete;
}
protected void Delete(object sender, EventArgs e)
{
ContainerParent?.DeleteItem(this);
Parent?.Controls?.Remove(this);
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
}
}
public class DeletableLabelItemContainer : UserControl
{
protected List<DeletableLabelItem> DeletableLabelItemList { get; } = new List<DeletableLabelItem>();
public DeletableLabelItemContainer()
{
//this.VScroll = true;
}
protected void Align()
{
int ypos = 0;
DeletableLabelItemList.ForEach(a => { a.Location = new Point(0, ypos); ypos = ypos + a.Height; });
}
public void DeleteItem(DeletableLabelItem item)
{
DeletableLabelItemList.Remove(item);
Controls.Remove(item);
Align();
}
public void DeleteItem(int index)
{
DeletableLabelItem item = DeletableLabelItemList.ElementAt(index);
DeletableLabelItemList.RemoveAt(index);
Controls.Remove(item);
Align();
}
public void Clear()
{
DeletableLabelItemList.Clear();
Controls.Clear();
Align();
}
public DeletableLabelItem Add(string Text = null, int? index = null)
{
DeletableLabelItem item = new DeletableLabelItem(Text ?? "Text", new Point(0, 0), this);
if (index is null) DeletableLabelItemList.Add(item);
else DeletableLabelItemList.Insert(index.Value, item);
Controls.Add(item);
Align();
return item;
}
public int Add(DeletableLabelItem item)
{
DeletableLabelItemList.Add(item);
Controls.Add(item);
Align();
return DeletableLabelItemList.IndexOf(item);
}
public int GetIndex(DeletableLabelItem item) => DeletableLabelItemList.IndexOf(item);
}
Использование:
Form f = new Form();
f.Show();
DeletableLabelItemContainer con = new DeletableLabelItemContainer();
f.Controls.Add(con);
var item1 = con.Add("test1");
var item2 = con.Add("test2");
Методы:
DeleteItem - удалить по ссылке или индексу
Clear - удалить все
Add - добавить новый
GetIndex - узнать индекс по ссылке
Так-же можете не использовать DeletableLabelItemContainer, а напрямую создавать DeletableLabelItem и помещать его на форму.