Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Form.Controls.OfType的奇怪行为_C#_.net_Winforms - Fatal编程技术网

C# Form.Controls.OfType的奇怪行为

C# Form.Controls.OfType的奇怪行为,c#,.net,winforms,C#,.net,Winforms,我有一个在运行时生成的表单,用户在其中输入一些数据,然后提交数据或取消。表单由一个TableLayoutPanel组成,该面板上有控件 我添加了提交和取消按钮,如下所示 TableLayoutPanel panel = new TableLayoutPanel { ColumnCount = 3, RowCount = gridObj.ColList.Count() + 1, Height = 800, Width = 800 }; /

我有一个在运行时生成的表单,用户在其中输入一些数据,然后提交数据或取消。表单由一个TableLayoutPanel组成,该面板上有控件

我添加了提交和取消按钮,如下所示

TableLayoutPanel panel = new TableLayoutPanel
{
       ColumnCount = 3,
       RowCount = gridObj.ColList.Count() + 1,
       Height = 800,
       Width = 800
 };

//other controls for user input...

    Button submitButton = new Button();
    submitButton.Text = "Submit";
    submitButton.Click += (sender, EventArgs) => { SubmitClick(sender, EventArgs, gridObj); };
    panel.Controls.Add(submitButton, 0, CurrentRow);
    this.AcceptButton = (submitButton);

    Button CancelButton = new Button();
    CancelButton.Text = "Cancel";
    panel.Controls.Add(CancelButton, 3, CurrentRow);
    this.CancelButton = (CancelButton);
有一种情况需要从表单中删除按钮。我使用以下代码来实现这一点

private void RemoveExistingButtons(TableLayoutPanel panel)
    {
        foreach (Control ctrl in panel.Controls.OfType<Button>())
        {
            panel.Controls.Remove(ctrl);
        }
    }
private void removeexisting按钮(TableLayoutPanel)
{
foreach(panel.Controls.OfType()中的控件ctrl)
{
面板。控件。移除(ctrl);
}
}
在我看来,这应该找到并删除面板上的每个按钮。 但是,它仅删除“提交”按钮。 取消按钮未被删除

我在玩它,通过添加另一个foreach,取消按钮被第二个foreach删除

private void RemoveExistingButtons(TableLayoutPanel panel)
    {
        foreach (Control ctrl in panel.Controls.OfType<Button>())
        {
            panel.Controls.Remove(ctrl);
        }
        foreach (Control ctrl in panel.Controls.OfType<Button>())
        {
            panel.Controls.Remove(ctrl);
        }
    }
private void removeexisting按钮(TableLayoutPanel)
{
foreach(panel.Controls.OfType()中的控件ctrl)
{
面板。控件。移除(ctrl);
}
foreach(panel.Controls.OfType()中的控件ctrl)
{
面板。控件。移除(ctrl);
}
}
我已经用其他控件类型测试过这种方法,它们成功地用一个循环删除了多个控件,这是“应该”的工作方式

 private void RemoveExistingControls(TableLayoutPanel panel)
    {
        foreach (Control ctrl in panel.Controls.OfType<Label>())
        {
            panel.Controls.Remove(ctrl);
        }
        foreach (Control ctrl in panel.Controls.OfType<TextBox>())
        {
            panel.Controls.Remove(ctrl);
        }
    }
private void移除现有控件(TableLayoutPanel)
{
foreach(panel.Controls.OfType()中的控件ctrl)
{
面板。控件。移除(ctrl);
}
foreach(panel.Controls.OfType()中的控件ctrl)
{
面板。控件。移除(ctrl);
}
}

我对此很困惑。我忽略了一些简单的东西吗?

您是否尝试了foreach(panel.Controls.OfType().ToList()中的Control ctrl)?这是一条众所周知的规则。不要更改正在枚举的集合。与其他框架集合类型不同,ControlCollection在修改集合后继续迭代时不会引发异常。实际上,您将跳过下一个控件。创建副本或使用for循环向后迭代。请注意,此代码在其他方面非常危险,可能导致永久内存泄漏。调用控件的Dispose()方法不是可选的。考虑一下,你可以通过简单地使控件不可见,将其可见属性设置为false。解决了这两个问题。我支持这一点。只要在满足条件时使控件enabled=false visible=false就行了。我会使用visible属性,但是,如果需要删除按钮,则可能会使用位于不同位置的submit/cancel按钮重建表单。