Foreach 跳过用户控件上的控件
Foreach skipping a control on usercontrol
我有一个用户控件,带有一个名为 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<string> mainAspects)
创建新的。
但是foreach循环只经过panel1和第一个标签,退出后(跳过第二个标签)。
我已经检查了在 foreach 循环之前有多少控件具有 this.Controls.Count.ToString()
的用户控件:它说,uc 有 3 个控件(使用 GetType()
函数我找到了一个面板和两个标签 - 所以它找到每个控件)。
所以在 CreateLabelsForMainAspetcs(List<string> mainAspects)
的第二个 运行 之后没有 3 个,而是 4 个控件。 1 个面板和 3 个标签。
之后,如果我只想显示一个标签:运行 列表中有一个字符串的处理代码和创建标签 - 用户控件上只有一个标签,第二个标签消失了。但是 Controls.Count
表示有 4 个控件 - 1 个面板和 3 个标签。你能帮忙吗,我做错了什么?
我猜测在遍历 Controls
集合时处理这些标签会篡改集合,因此停止对第一个处理的标签进行迭代。
你为什么不尝试将它们添加到 List<Label>
而不是丢弃。当所有 Label 控件都添加到 List 时,遍历该列表并将它们删除。
所以,而不是
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();
}
选项一:您能否在控件中使用列表框:如果是,则在 UC 中使用列表框并在您的父级中维护一个列表并将 UC ListBox.source 设置为列表。这应该会在您调整列表时自动更新
选项二
创建一个默认视图 (Usercontrol.Clear()) 过程,首先调用它而不是 运行 您的代码以添加新标签。
此调用可以对用户不可见,或者您可以强制清除调用
我有一个用户控件,带有一个名为 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<string> mainAspects)
创建新的。
但是foreach循环只经过panel1和第一个标签,退出后(跳过第二个标签)。
我已经检查了在 foreach 循环之前有多少控件具有 this.Controls.Count.ToString()
的用户控件:它说,uc 有 3 个控件(使用 GetType()
函数我找到了一个面板和两个标签 - 所以它找到每个控件)。
所以在 CreateLabelsForMainAspetcs(List<string> mainAspects)
的第二个 运行 之后没有 3 个,而是 4 个控件。 1 个面板和 3 个标签。
之后,如果我只想显示一个标签:运行 列表中有一个字符串的处理代码和创建标签 - 用户控件上只有一个标签,第二个标签消失了。但是 Controls.Count
表示有 4 个控件 - 1 个面板和 3 个标签。你能帮忙吗,我做错了什么?
我猜测在遍历 Controls
集合时处理这些标签会篡改集合,因此停止对第一个处理的标签进行迭代。
你为什么不尝试将它们添加到 List<Label>
而不是丢弃。当所有 Label 控件都添加到 List 时,遍历该列表并将它们删除。
所以,而不是
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();
}
选项一:您能否在控件中使用列表框:如果是,则在 UC 中使用列表框并在您的父级中维护一个列表并将 UC ListBox.source 设置为列表。这应该会在您调整列表时自动更新
选项二 创建一个默认视图 (Usercontrol.Clear()) 过程,首先调用它而不是 运行 您的代码以添加新标签。 此调用可以对用户不可见,或者您可以强制清除调用