如何使用tag属性删除动态添加的控件

时间:2012-12-15 19:53:24

标签: c# winforms

我有一个带有按钮的窗体,当点击按钮时它会动态生成控件,还会添加一个动态生成的按钮,这样它就会删除符合条件的控件,意思是放在按钮旁边,一排单击按钮我的代码

时将删除控件
int c = 0;
        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)// this is the dynamically added button's event which will remove the combobox and textbox
        {
            Button btnh = sender as Button;
            foreach (Control item in panel1.Controls.OfType<TextBox>())
            {
                if (item.Tag == sender || item == sender)
                    panel1.Controls.Remove(item);
            }
            foreach (Control item in panel1.Controls.OfType<ComboBox>())
            {
                if (item.Tag == sender || item == sender)
                    panel1.Controls.Remove(item);
            }
            panel1.Controls.Remove(btnh);
        }

我的错误是什么,但问题是dosnt删除它留下控件的所有控件,我不知道什么是我的代码简单易行的问题,但我不知道它缺乏的地方

2 个答案:

答案 0 :(得分:3)

问题是您在循环收集集时删除项目。在这种情况下,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);
    }
}

答案 1 :(得分:3)

删除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有效但我不确定:)