Удаление динамических элементов управления с панели

У меня есть динамически сгенерированные элементы управления на панели форм 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);
  }

Теперь, как удалить все элементы управления из строки, нажав кнопку из этой строки?

Ответ 1

Вы все еще не говорите, какой элемент управления вы хотите удалить, какие типы элементов управления вы хотите удалить или как их идентифицировать.

Вы можете просто пропустить элементы управления, чтобы удалить определенные элементы управления.

Если у вас 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:

Легко сделать то же самое, так как вы уже пометили элемент управления. Все, что вам нужно, это просто вернуть элемент управления из тега. Но вам нужно соответствующим образом пометить:

Сделайте это вместо:

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

Ответ 2

Если у вас есть панель другого контейнера с более динамическими компонентами для удаления всего или более одного, вы можете продолжить таким образом.

На первом этапе вы загружаете компонент в массив или список.

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

Ответ 3

Если все элементы управления, которые вы хотите удалить, находятся в панели, вы можете: panel.Controls.Clear(); Это очищает все элементы управления от панели.

Ответ 4

Удалить события управления. Из MSDN:

Чтобы программно удалить элементы управления из коллекции

  • Удалите обработчик события из события. В Visual Basic используйте RemoveHandler Statement; в Visual С# используйте - = Оператор (ссылка на С#).
  • Используйте метод Удалить, чтобы удалить требуемый элемент управления из панели Элементы управления.
  • Вызвать метод Dispose освободить все ресурсы, используемые элементом управления.

Конкретные примеры приведены с использованием VB и С# на связанной странице.