【问题标题】:Foreach skipping a control on usercontrolForeach 跳过用户控件上的控件
【发布时间】:2017-03-08 18:08:53
【问题描述】:

我有一个用户控件,带有一个名为 panel1 的面板。我在设计器视图中添加了它。 从组合框中选择一个选项后,在这种情况下,我向用户控件添加两个标签(mainAspects 有两个字符串):

private void CreateLabelsForMainAspetcs(List<string> mainAspects)
    {
        int mainCount;
        int firstLabelX;
        int firstLabelY;
        int addToFirstLabelY = 0;

        mainCount = mainAspects.Count;
        firstLabelX = 22;
        firstLabelY = 149;

        for (int i = 0; i < mainCount; i++)
        {
                Label mainAsp = new Label();
                mainAsp.Text = mainAspects[i];
                mainAsp.Location = new Point(firstLabelX, firstLabelY + addToFirstLabelY);
                mainAsp.AutoSize = true;
                Controls.Add(mainAsp);
                addToFirstLabelY = addToFirstLabelY + 100;
        }
    }

之后,当用户从组合框中选择其他选项时,我想使用以下代码处理标签:

 foreach (Control ctrl in this.Controls)
            {
                if (ctrl is Label)
                    ctrl.Dispose();
            }

并使用CreateLabelsForMainAspetcs(List&lt;string&gt; mainAspects) 创建新的。 但是 foreach 循环只经过 panel1 和第一个标签,然后退出(跳过第二个标签)。

我已经在 foreach 循环之前检查了有多少个带有this.Controls.Count.ToString() 的用户控件:它说,uc 有 3 个控件(使用GetType() 函数,我找到了一个面板和两个标签 - 所以它找到了每个控件)。

所以在第二次运行CreateLabelsForMainAspetcs(List&lt;string&gt; mainAspects) 之后,不是 3 个,而是 4 个控件。 1 个面板和 3 个标签。

之后,如果我只想显示一个标签:运行 dispose 代码和 createlabel 与 List 中的一个字符串 - 用户控件上只有一个标签,第二个标签消失。但是Controls.Count 说有 4 个控件 - 1 个面板和 3 个标签。你能帮忙吗,我做错了什么?

【问题讨论】:

  • 我错误地认为调用 dispose 什么都不做?由于 Controls 中仍然存在对您要处理的标签的引用?也许从控件中删除标签然后处理它。

标签: c# foreach user-controls


【解决方案1】:

我猜想在迭代 Controls 集合时处理这些标签会篡改集合,因此会停止对第一个处理的标签进行迭代。

您为什么不尝试将它们添加到List&lt;Label&gt; 而不是丢弃。当所有标签控件都添加到列表中时,循环遍历该列表并删除它们。

所以,而不是

foreach (Control ctrl in this.Controls)
{
    if (ctrl is Label)
        ctrl.Dispose();
}

试试

List<Label> labelList = this.Controls.OfType<Label>().ToList();
foreach(Label lbl in labelList)
{
    lbl.Dispose();
}

【讨论】:

    【解决方案2】:

    选项一:您能否在控件中使用 ListBox:如果是,则在 UC 中使用 ListBox 并在您的父级中维护一个 List 并将 UC ListBox.source 设置为列表。这应该会在您调整列表时自动更新

    选项二 创建一个默认视图 (Usercontrol.Clear()) 过程,首先调用它,然后运行您的代码来添加新标签。 此调用可能对用户视而不见,或者您可以强制清除调用

    【讨论】:

      猜你喜欢
      • 2015-04-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-07
      相关资源
      最近更新 更多