如何使用标签属性删除动态添加的控件
Posted
技术标签:
【中文标题】如何使用标签属性删除动态添加的控件【英文标题】:how to remove the dynamically added control using tag property 【发布时间】:2012-12-03 10:55:31 【问题描述】:我有一个窗口窗体,它有一个按钮,当单击按钮时,它会动态生成控件,还会添加一个动态生成的按钮,以便它会删除排队的控件,这意味着除了按钮之外,还有一行单击按钮时将删除控件我的代码是
int c = 0; 私人无效按钮1_Click(对象发送者,EventArgs e) 诠释诉; v = c++; panel1.VerticalScroll.Value = VerticalScroll.Minimum; 按钮 btn = new Button(); btn.Name = "btn" + v; btn.Text = "删除"; btn.Location = new Point(750, 5 + (30 * v)); btn.Click += new EventHandler(btn_Click); 组合框组合 = 新组合框(); combo.Name = "组合框" + v; combo.Location = new Point(30, 5 + (30 * v)); 组合.标签 = btn; 组合框combo2 =新组合框(); combo2.Name = "combobox2" + v; combo2.Location = new Point(170, 5 + (30 * v)); 组合2.标签= btn; 文本框 txt = 新文本框(); txt.Name = "txtbx" + v; txt.Location = new Point(300, 5 + (30 * v)); txt.标签 = btn; 文本框 txt2 = 新文本框(); txt2.Name = "txtbx2" + v; txt2.Location = new Point(450, 5 + (30 * v)); txt2.标签 = btn; 文本框 txt3 = 新文本框(); txt3.Name = "txtbx3" + v; txt3.Location = new Point(600, 5 + (30 * v)); txt3.标签 = btn; panel1.Controls.Add(组合); 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)// 这是动态添加的按钮事件,它将删除组合框和文本框 按钮 btnh = 作为按钮的发送者; foreach(panel1.Controls.OfType() 中的控制项) if (item.Tag == 发件人 || item == 发件人) panel1.Controls.Remove(item); foreach(panel1.Controls.OfType () 中的控制项) if (item.Tag == 发件人 || item == 发件人) panel1.Controls.Remove(item); panel1.Controls.Remove(btnh);
我的错误没什么,但问题是它不会删除它留下的所有控件,我不知道是什么问题我的代码简单易行,但我不知道它缺少什么
【问题讨论】:
这个执行是只在C#
还是你在做任何interop
?
看看这个 MSDN Link 'Control.Tag Property'-msdn.microsoft.com/en-us/library/…
我在windows窗体下工作,我不了解其他人,对不起,我的英语不太好,如果我误解了你
@DJKRAZE 我正在将对象绑定到其他对象,以便可以将其删除,
好的,只是想更清楚地了解您的火车在哪里......谢谢
【参考方案1】:
问题是您在遍历集合时正在删除项目。在这种情况下,foreach 语句可能会跳过项目。首先将要删除的项目存储在列表中:
List<Control> toBeRemoved = panel1.Controls
.Cast<Control>()
.Where(c => c.Tag == sender)
.ToList();
foreach (Control c in toBeRemoved)
panel1.Controls.Remove(c);
如果您向后循环,您也可以轻松地在循环中删除:
for (int i = panel1.Controls.Count - 1; i >= 0; i--)
if (panel1.Controls[i].Tag == sender)
panel1.Controls.RemoveAt(i);
【讨论】:
谢谢,但如果你能解释一下这个 ListControls
集合没有实现IEnumerable<T>
,但 LINQ 是其中之一。所以Cast<Control>
将Controls
集合转换为IEnumerable<Control>
。然后Where
子句选择Tag
等于sender
(按钮)的控件。最后用结果创建一个列表。表达式 c => c.Tag == sender
是一个 lambda 表达式。您可以将其视为编写函数方法的一种非常简洁的方式。 Where
子句使用该函数来测试枚举的项。
我的解决方案删除了 Tag 等于发送者的控件,但不删除发送者本身。
另见Language-Integrated Query (LINQ)和Lambda Expressions (Eric White's Blog)和Lambda Expressions (C# Programming Guide)【参考方案2】:
在 foreach 循环中删除项目通常会导致列表在您遍历时发生更改。
这个 linq 应该可以解决问题:
private void btn_Click(object sender, EventArgs e)// this is the dynamically added button's event which will remove the combobox and textbox
Button btnh = sender as Button;
panel1.Controls.OfType<TextBox>().Where(i => i.Tag == sender || i == sender).ToList().ForEach(i => panel1.Controls.Remove(i));
panel1.Controls.OfType<ComboBox>().Where(i => i.Tag == sender || i == sender).ToList().ForEach(i => panel1.Controls.Remove(i));
panel1.Controls.Remove(btnh);
为什么 linq foreach 有效,但我不确定 :)
【讨论】:
不客气。我认为这行得通的原因是ToList()
创建了一个临时列表,但我也不完全确定。
@JGaarsdal,是的,在ToList()
之后,您正在处理一个临时列表(IL 创建一个局部变量),然后从另一个列表中删除项目。这就是它工作的原因。你的猜测是正确的。以上是关于如何使用标签属性删除动态添加的控件的主要内容,如果未能解决你的问题,请参考以下文章
VC中Tab控件怎么能够动态的增加标签,删除标签,就像浏览器那样的,能给个具体例子更好,谢谢了哈