我试图在Windows窗体应用程序中一次删除多个控件(文本框和复选框)。基本上,我有一行文本框和一个相应的复选框。当"删除行"单击按钮,它应删除已选择的所有行。但它似乎一次只删除两个或三个(每行相同的两个或三个,但似乎没有任何理由它选择相同的两个或三个)。我附上了一些屏幕截图,显示了正在发生的事情。
以下是相关代码:
//Gets a list of all ticked checkboxes
public List<string> checkForChecked()
{
var allCheckboxes = tabPage1.GetAllControlsOfType<CheckBox>();
int count = allCheckboxes.Count<CheckBox>();
List<string> checkedChecks = new List<string>();
foreach(Control c in tabPage1.Controls)
{
if(c is CheckBox && ((CheckBox)c).Checked)
{
checkedChecks.Add(c.Name.ToString());
}
}
return checkedChecks;
}
//The button click. Loop through elements and remove ones with the right name
private void button2_Click(object sender, System.EventArgs e)
{
List<string> toDelete = checkForChecked();
foreach (var val in toDelete)
{
foreach (Control item in tabPage1.Controls.OfType<Control>())
{
if (item.Name == val.ToString())
{
tabPage1.Controls.Remove(item);
}
}
}
}
我使用的是Windows窗体应用,没有使用asp或其他网络技术。
答案 0 :(得分:1)
在枚举时从集合中删除项目是一个常见错误。例如:
foreach (Control c in Controls)
Controls.Remove(c);
将仅删除一半控件并保留每一秒控件。
一般问题的一些常见解决方案是:
在您的情况下,两种方法都可以组合成这样的方式(.Find
返回Control[]
):
foreach (var cb in tabPage1.Controls.OfType<CheckBox>())
if (cb.Checked)
foreach (var c in tabPage1.Controls.Find(cb.Name, false))
tabPage1.Controls.Remove(c)
答案 1 :(得分:0)
您可以尝试更多类似的内容:
private void button2_Click(object sender, EventArgs e)
{
List<CheckBox> CheckedBoxes = new List<CheckBox>();
foreach (CheckBox cb in tabPage1.Controls.OfType<CheckBox>())
{
if (cb.Checked)
{
CheckedBoxes.Add(cb);
}
}
foreach (CheckBox cb in CheckedBoxes)
{
string cbName = cb.Name;
cb.Dispose();
// ... probably more code in here to find the other controls
// ... in the "row" based on "cbName"
}
}
答案 2 :(得分:0)
您正在迭代控件集合并删除一个控件,每次调用Remove()方法时,该控件都会影响集合中每个项目的索引。这可能会与foreach中的迭代器混淆,从而导致“跳过”行为。从任何控件集合中删除时,最好不要同时迭代它。此外,当您在要删除项目的Controls集合上循环时,请将循环编码为迭代器向后工作。
for (var i=Parent.Controls.Count-1; i >=0; i--)
{
if (someCondition) Parent.Controls.Remove(Parent.Controls[i]);
}
以下是您的代码的清洁版本。从CheckForChecked方法返回的列表现在是一个控件列表,它比控件名称列表更容易使用。
在删除中,我们正在迭代要删除的事物列表,而不是我们要删除的控件集合。
//Gets a list of all ticked checkboxes
public List<Control> CheckForChecked()
{
var tabPage1 = new TabPage();
var results = new List<Control>(0);
results.AddRange(from Control c in tabPage1.Controls
where c is CheckBox && (c as CheckBox).Checked
select c);
return results;
}
//The button click. Loop through elements and remove ones with the right name
private void button2_Click(object sender, System.EventArgs e)
{
var toDelete = CheckForChecked();
var tabPage1 = new TabPage();
foreach (var val in toDelete.Where(val => tabPage1.Controls.Contains(val)))
{
tabPage1.Controls.Remove(val);
}
}
希望这有助于某人。