从面板中删除动态控件

时间:2012-12-15 01:48:53

标签: c# winforms panel dynamic-controls

我在Windows窗体的面板上动态生成控件,我还生成了一个用于删除控件的按钮,所有这些都是行。

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);
  }

现在,如何在点击该行的按钮时从一行中删除所有控件?

5 个答案:

答案 0 :(得分:30)

您仍然没有说要删除哪个控件,要删除的控件类型或识别方式。

您可以循环浏览控件以删除特定控件。

如果你有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
        }
    }
}

修改

由于您已经对控件进行了标记,因此很容易做到这一点。您只需从标签中检索控件即可。 但您需要适当标记:

请改为:

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); 
    }
}

在这里,您使用按钮标记控件,因此在按钮单击时,您可以删除所有控件,其标签是从sender参数获得的单击按钮。但这种方法的缺点是你必须枚举面板的所有控件都不是很好。

编辑:当我开始学习时,下面的代码是针对OP目前尚未使用的表格布局面板。但无论如何,桌面布局更适合这项工作。

我建议你这样做:

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;
        }
    }
}

答案 1 :(得分:4)

如果你有一个面板o其他容器有更多dinamicaly组件用于删除所有或多个,你可以这样做。

在第一步中,您可以在数组或列表中加载组件。

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();
}

答案 2 :(得分:2)

如果要删除的所有控件都在Panel中,您可以执行以下操作: panel.Controls.Clear();清除面板中的所有控件。

答案 3 :(得分:0)

由于控件是在运行时添加的,因此在使用findName方法和register方法之前,请先注册它们。

StackPanel sp = new StackPanel
{
   Name = "mySP",
   Orientation = Orientation.Horizontal,
};

//need to register the control to find it by name
RegisterName(sp.Name, sp);

//now to find control by name 
StackPanel sp = (StackPanel)mainStackPanel.FindName("mySP");

//deleting the control found
mainStackPanel.Children.Remove(sp);

//if you need to use the same name again, you have to unregister too
UnregisterName(sp.Name);

答案 4 :(得分:-1)

删除控制事件。 From MSDN

  

以编程方式从集合中删除控件

     
      
  1. 从事件中删除事件处理程序。在Visual Basic中,使用RemoveHandler Statement关键字;在Visual C#中,使用-= Operator (C# Reference)
  2.   
  3. 使用删除方法从面板的控件集合中删除所需的控件。
  4.   
  5. 调用Dispose方法以释放控件使用的所有资源。
  6.   

在链接页面中使用VB和C#给出了具体示例。