C# 从面板中删除动态控件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13888558/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Removing dynamic controls from panel
提问by shariq_khan
I have dynamically generated controls on the panels of windows form and i have also generated a button for removing the controls, all in rows.
我在窗体的面板上动态生成了控件,并且我还生成了一个用于删除控件的按钮,所有控件都在行中。
int c = 0;
private void button1_Click(object sender, EventArgs e)
{
int v;
v = c++;
panel1.VerticalScroll.Value = VerticalScroll.Minimum;
ComboBox combo = new ComboBox();
combo.Name = "combobox" + v ;
combo.Location = new Point(30, 5 + (30 * v));
ComboBox combo2 = new ComboBox();
combo2.Name = "combobox2" + v ;
combo2.Location = new Point(170, 5 + (30 * v));
TextBox txt = new TextBox();
txt.Name = "txtbx" + v;
txt.Location = new Point(300, 5 + (30 * v));
TextBox txt2 = new TextBox();
txt2.Name = "txtbx2" + v;
txt2.Location = new Point(450, 5 + (30 * v));
TextBox txt3 = new TextBox();
txt3.Name = "txtbx3" + v;
txt3.Location = new Point(600, 5 + (30 * v));
Button btn = new Button();
btn.Name = "btn" + v;
btn.Text = "Remove";
btn.Location = new Point(750, 5 + (30 * v));
panel1.Controls.Add(combo);
panel1.Controls.Add(btn);
panel1.Controls.Add(txt);
panel1.Controls.Add(combo2);
panel1.Controls.Add(txt2);
panel1.Controls.Add(txt3);
btn.Click += new EventHandler(btn_Click);
combo.Tag = btn;
combo2.Tag = combo;
btn.Tag = combo2;
}
private void btn_Click(object sender, EventArgs e)
{
ComboBox cb3 = btnh.Tag as ComboBox;
ComboBox cb4 = cb3.Tag as ComboBox;
panel1.Controls.Remove(cb3);
panel1.Controls.Remove(cb4);
panel1.Controls.Remove(btnh);
}
Now how do I remove all the controls from a row upon clicking a button from that row?
现在如何在单击该行中的按钮时从该行中删除所有控件?
采纳答案by nawfal
You are still not saying which control you want to remove, what type of controls you want to remove or how you want to identify them.
您仍然没有说要删除哪个控件、要删除什么类型的控件或要如何识别它们。
You could just loop through the controls to remove specific Controls.
您可以循环浏览控件以删除特定控件。
If you have Linq, its easy:
如果你有Linq,它很容易:
private void btn_Click(object sender, EventArgs e)
{
panel1.Controls.Clear(); //to remove all controls
//to remove all comboboxes
foreach (Control item in panel1.Controls.OfType<ComboBox>())
{
panel1.Controls.Remove(item);
}
//to remove control by Name
foreach (Control item in panel1.Controls.OfType<Control>())
{
if (item.Name == "bloodyControl")
panel1.Controls.Remove(item);
}
//to remove just one control, no Linq
foreach (Control item in panel1.Controls)
{
if (item.Name == "bloodyControl")
{
panel1.Controls.Remove(item);
break; //important step
}
}
}
Edit:
编辑:
Its easy to do the same since you're tagging the control already. All you need is to just retrieve the control back from tag. But you need to tag appropriately:
由于您已经标记了控件,因此很容易执行相同的操作。您所需要的只是从标签中检索控制权。但是你需要适当地标记:
Do this instead:
改为这样做:
private void button1_Click(object sender, EventArgs e)
{
int v;
v = c++;
panel1.VerticalScroll.Value = VerticalScroll.Minimum;
Button btn = new Button();
btn.Name = "btn" + v;
btn.Text = "Remove";
btn.Location = new Point(750, 5 + (30 * v));
btn.Click += new EventHandler(btn_Click);
ComboBox combo = new ComboBox();
combo.Name = "combobox" + v ;
combo.Location = new Point(30, 5 + (30 * v));
combo.Tag = btn;
ComboBox combo2 = new ComboBox();
combo2.Name = "combobox2" + v ;
combo2.Location = new Point(170, 5 + (30 * v));
combo2.Tag = btn;
TextBox txt = new TextBox();
txt.Name = "txtbx" + v;
txt.Location = new Point(300, 5 + (30 * v));
txt.Tag = btn;
TextBox txt2 = new TextBox();
txt2.Name = "txtbx2" + v;
txt2.Location = new Point(450, 5 + (30 * v));
txt2.Tag = btn;
TextBox txt3 = new TextBox();
txt3.Name = "txtbx3" + v;
txt3.Location = new Point(600, 5 + (30 * v));
txt3.Tag = btn;
panel1.Controls.Add(combo);
panel1.Controls.Add(btn);
panel1.Controls.Add(txt);
panel1.Controls.Add(combo2);
panel1.Controls.Add(txt2);
panel1.Controls.Add(txt3);
}
private void btn_Click(object sender, EventArgs e)
{
//to remove control by Name
foreach (Control item in panel1.Controls.OfType<Control>())
{
if (item.Tag == sender || item == sender)
panel1.Controls.Remove(item);
}
}
Here you are tagging controls with the button, hence on the button click you can remove all the controls whose tags are the clicked button which you get from senderargument. But the downside of this approach is that you have to enumerate all the controls of the panel which is not great.
在这里,您使用按钮标记控件,因此在单击按钮时,您可以删除所有控件,其标签是您从sender参数中获得的单击按钮。但是这种方法的缺点是你必须枚举面板的所有控件,这不是很好。
Edit: As I came to learn the below code is for a table layout panel which the OP isn't using for now. But anyway a table panel layout is better suited for this job.
编辑:当我开始学习以下代码时,该代码适用于 OP 暂时未使用的表格布局面板。但无论如何,表格面板布局更适合这项工作。
I would suggest you to do this:
我建议你这样做:
private void button1_Click(object sender, EventArgs e)
{
int v;
v = c++;
panel1.VerticalScroll.Value = VerticalScroll.Minimum;
Button btn = new Button();
btn.Name = "btn" + v;
btn.Text = "Remove";
btn.Location = new Point(750, 5 + (30 * v));
btn.Click += new EventHandler(btn_Click);
btn.Tag = v;
ComboBox combo = new ComboBox();
combo.Name = "combobox" + v ;
combo.Location = new Point(30, 5 + (30 * v));
combo.Tag = v;
ComboBox combo2 = new ComboBox();
combo2.Name = "combobox2" + v ;
combo2.Location = new Point(170, 5 + (30 * v));
combo2.Tag = v;
TextBox txt = new TextBox();
txt.Name = "txtbx" + v;
txt.Location = new Point(300, 5 + (30 * v));
txt.Tag = v;
TextBox txt2 = new TextBox();
txt2.Name = "txtbx2" + v;
txt2.Location = new Point(450, 5 + (30 * v));
txt2.Tag = v;
TextBox txt3 = new TextBox();
txt3.Name = "txtbx3" + v;
txt3.Location = new Point(600, 5 + (30 * v));
txt3.Tag = v;
panel1.Controls.Add(combo);
panel1.Controls.Add(btn);
panel1.Controls.Add(txt);
panel1.Controls.Add(combo2);
panel1.Controls.Add(txt2);
panel1.Controls.Add(txt3);
}
private void btn_Click(object sender, EventArgs e)
{
int toBeDeletedRow = (int)((Control)sender).Tag;
for (int row = panel1.RowCount - 1; row >= 0; row--)
{
if (row == toBeDeletedRow)
{
panel1.RowStyles.RemoveAt(row);
panel1.RowCount--;
return;
}
}
}
回答by body90
Remove control events. From MSDN:
删除控制事件。从 MSDN:
To remove controls from a collection programmatically
- Remove the event handler from the event. In Visual Basic, use the RemoveHandler Statementkeyword; in Visual C#, use the -= Operator (C# Reference).
- Use the Removemethod to delete the desired control from the panel's Controlscollection.
- Call the Disposemethod to release all the resources used by the control.
以编程方式从集合中删除控件
- 从事件中删除事件处理程序。在 Visual Basic 中,使用RemoveHandler Statement关键字;在 Visual C# 中,使用-= 运算符(C# 参考)。
- 使用Remove方法从面板的Controls集合中删除所需的控件。
- 调用Dispose方法释放控件使用的所有资源。
Specific examples are given using VB and C# in the linked page.
在链接页面中使用 VB 和 C# 给出了具体示例。
回答by daniele3004
If you have a Panel o other container with more dinamicaly components for remove all or more than oneyou can proceed in this way.
如果您有一个 Panel o 其他容器,其中包含更多用于删除所有或多个组件的组件,您可以通过这种方式进行。
In first step you load a component in array or list.
在第一步中,您加载数组或列表中的组件。
List<PersonalUserControl> lst = new List<PersonalUserControl>();
foreach (Object obj in this.PanelImplementationTeam.Controls)
{
//DO NOT REMOVE COMPONENT IN THIS LOOP BECAUSE
//YOU DECREASE THE .Controls ARRAY AND YOU WILL HAVE AN ERROR
if (obj is PersonalUserControl)
{
lst.Add((PersonalUserControl)obj);
}
}
foreach(PersonalUserControl uc in lst)
{
uc.Dispose();
}
回答by Flare Flax
If all of your controls that you want to delete are in a Panel, you can do:
panel.Controls.Clear();That clears all controls form your panel.
如果您要删除的所有控件都在面板中,您可以执行以下操作:
panel.Controls.Clear();清除面板中的所有控件。

