C# Win Forms 删除动态创建的控件时出现问题
C# Win Forms issues deleting dynamically created controls
我有一个函数可以从数据库中读取信息,并在从组合框中选择菜单项时动态创建复选框控件。
当用户从组合框中选择不同的项目时,我试图删除页面上已有的任何现有复选框。但是,删除功能只会删除每隔一个复选框。知道我做错了什么吗?
表单非常基本,只有一个表单,没有选项卡,只有这个组合框和动态创建的复选框。
private void serverModels_SelectedIndexChanged(object sender, EventArgs e)
{
DeleteBoxes();
List<string> eqpIDs = new List<string>();
try
{
DataExtractor dataExtract = new DataExtractor(DataBase.TCDBServerName, DataBase.TCDBname, DataBase.TCDBUserID, DataBase.TCDBPassword);
eqpIDs = dataExtract.GetToolsByServerModel(Convert.ToString(serverModels.SelectedItem));
}
catch (Exception ex)
{
Logger.InsertSystemLog(e.ToString());
MessageBox.Show(ex.ToString());
return;
}
for(int i = 0; i < eqpIDs.Count; i++)
{
CheckBox box = new CheckBox();
box.Checked = true;
box.Tag = "TOOL";
box.Text = eqpIDs[i];
box.AutoSize = true;
box.Location = new Point(50 + 75 * (i / 17), (i % 17) * 25 + 120);
this.Controls.Add(box);
}
}
private void DeleteBoxes()
{
foreach (Control c in this.Controls)
{
if (c is CheckBox && c.Tag.ToString() == "TOOL" )
c.Dispose();
}
}
这似乎是因为您正在修改控件的 Controls
集合,同时迭代它。尝试这样的事情:
private void DeleteBoxes()
{
List<Control> toDispose = new List<Control>();
foreach (Control c in this.Controls)
{
if (c is CheckBox && c.Tag.ToString() == "TOOL" )
toDispose.Add(c);
}
foreach (Control c in toDispose)
{
c.Dispose();
}
}
Dispose 正在从 Controls 集合中移除控件并释放该控件。
如前所述here、
When a Control is removed from the control collection, all subsequent controls are moved up one position in the collection.
这就是您的逻辑跳过所有其他 CheckBox 的原因。
尝试像这样反向使用 for 循环:
for (int ii = Controls.Count - 1; ii >= 0; ii--)
{
if (Controls[ii] is CheckBox && Controls[ii].Tag.ToString() == "TOOL")
Controls[ii].Dispose();
}
我有一个函数可以从数据库中读取信息,并在从组合框中选择菜单项时动态创建复选框控件。
当用户从组合框中选择不同的项目时,我试图删除页面上已有的任何现有复选框。但是,删除功能只会删除每隔一个复选框。知道我做错了什么吗?
表单非常基本,只有一个表单,没有选项卡,只有这个组合框和动态创建的复选框。
private void serverModels_SelectedIndexChanged(object sender, EventArgs e)
{
DeleteBoxes();
List<string> eqpIDs = new List<string>();
try
{
DataExtractor dataExtract = new DataExtractor(DataBase.TCDBServerName, DataBase.TCDBname, DataBase.TCDBUserID, DataBase.TCDBPassword);
eqpIDs = dataExtract.GetToolsByServerModel(Convert.ToString(serverModels.SelectedItem));
}
catch (Exception ex)
{
Logger.InsertSystemLog(e.ToString());
MessageBox.Show(ex.ToString());
return;
}
for(int i = 0; i < eqpIDs.Count; i++)
{
CheckBox box = new CheckBox();
box.Checked = true;
box.Tag = "TOOL";
box.Text = eqpIDs[i];
box.AutoSize = true;
box.Location = new Point(50 + 75 * (i / 17), (i % 17) * 25 + 120);
this.Controls.Add(box);
}
}
private void DeleteBoxes()
{
foreach (Control c in this.Controls)
{
if (c is CheckBox && c.Tag.ToString() == "TOOL" )
c.Dispose();
}
}
这似乎是因为您正在修改控件的 Controls
集合,同时迭代它。尝试这样的事情:
private void DeleteBoxes()
{
List<Control> toDispose = new List<Control>();
foreach (Control c in this.Controls)
{
if (c is CheckBox && c.Tag.ToString() == "TOOL" )
toDispose.Add(c);
}
foreach (Control c in toDispose)
{
c.Dispose();
}
}
Dispose 正在从 Controls 集合中移除控件并释放该控件。
如前所述here、
When a Control is removed from the control collection, all subsequent controls are moved up one position in the collection.
这就是您的逻辑跳过所有其他 CheckBox 的原因。
尝试像这样反向使用 for 循环:
for (int ii = Controls.Count - 1; ii >= 0; ii--)
{
if (Controls[ii] is CheckBox && Controls[ii].Tag.ToString() == "TOOL")
Controls[ii].Dispose();
}