0

ボタンのあるウィンドウフォームがあります。ボタンをクリックすると、動的に生成されたコントロールが追加されます。また、動的に生成されたボタンが追加され、一列に並んでいるコントロールが削除されます。つまり、ボタンの横に、コントロールの行が表示されます。ボタンがクリックされたときに削除された私のコードは

int c = 0;
        private void button1_Click(object sender、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);

            ComboBoxコンボ=新しい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)//これは動的に追加されたボタンのイベントであり、コンボボックスとテキストボックスを削除します
        {{
            ボタンbtnh=ボタンとしての送信者;
            foreach(panel1.Controls.OfType <TextBox>()のコントロールアイテム)
            {{
                if(item.Tag==送信者||item ==送信者)
                    panel1.Controls.Remove(item);
            }
            foreach(panel1.Controls.OfType <ComboBox>()のコントロールアイテム)
            {{
                if(item.Tag==送信者||item ==送信者)
                    panel1.Controls.Remove(item);
            }
            panel1.Controls.Remove(btnh);
        }

私のエラーは何も問題ではありませんそれはそれがコントロールを残すすべてのコントロールを削除しないことですそして私は私のコードがシンプルで簡単な問題が何であるかわかりませんがそれがどこに欠けているのかわかりません

4

2 に答える 2

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);
    }
}
于 2012-12-15T20:07:54.410 に答える
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);
    }

linqforeachが機能する理由はわかりませんが:)

于 2012-12-15T20:22:03.023 に答える