我有一个带有5个CheckBoxes的checkedListBox,我希望第一个是“All”。 我写下了这段代码但是我得到了一个无限循环:
private void chkLstBx_ItemCheck(object sender, ItemCheckEventArgs e)
{
// ----- Get the name of the CheckBox that's changed: -----
string selected = chkLstBx.SelectedItem + "";
// ----- If "All" changed: -----
if (selected.Equals("All"))
// ----- to TRUE(from unchecked): -----
if (("" + (chkLstBx.GetItemCheckState(0))).Equals("Unchecked"))
for (int i = 1; i < chkLstBx.Items.Count; i++)
**chkLstBx.SetItemChecked(i, true);**
else // ----- to FALSE(from checked): -----
for (int i = 1; i < chkLstBx.Items.Count; i++)
chkLstBx.SetItemChecked(i, false);
// -----------------------------------------------
// -------------- REST OF CODE HERE --------------
// -----------------------------------------------
}
粗体线(**)不幸地再次调用“chkLstBx_ItemCheck”...递归...导致无限循环,其中所选的总是“全部”,仍然是“未选中”,并且我再次从1开始。 我该如何解决这个问题?
答案 0 :(得分:2)
在此代码中,请注意这会使用列表中的第一项作为All
项。这是一个很好的做法,但更好的做法是保留所有项目的引用,并使用它来检查事件处理程序中检查的项目。
private void chkLstBx_ItemCheck(object sender, ItemCheckEventArgs e)
{
if (e.Index == 0)
{
if (e.NewValue == CheckState.Checked)
ChangeAllCheckBoxValues(true);
else
ChangeAllCheckBoxValues(false);
}
}
private void ChangeAllCheckBoxValues(bool value)
{
for (int i = 1; i < chkLstBx.Items.Count; i++)
{
chkLstBx.SetItemChecked(i, value);
}
}
答案 1 :(得分:0)
我试图查看您的代码和我想到的两件事:
1)原因是ItemCheck的绑定是针对chkListBx而不是特定的行,因此当您更改特定行的项检查时,它会再次调用此方法 - 查找是什么选择值并再次调用该方法。我能够通过将绑定更改为&#39; SelectedIndexChanged&#39; - 尽管您可能需要检查它是否与其余代码一起使用。
2)当将绑定更改为&#39; SelectedIndexChanged&#39;时,我得到的行为有点相反(即:All仍未选中,所有其他复选框都已选中)。原因是当它之前未经检查时 - 当我点击它时,它将值设置为“已检查”。 - 因此在进行评估时 - 该值被视为检查 - 并且它将取消选择&#39;所有。
注意:在旁注中,即使对于单行也总是有大括号
for (int i = 1; i < chkLstBx.Items.Count; i++)
chkLstBx.SetItemChecked(i, false);
进入
for (int i = 1; i < chkLstBx.Items.Count; i++)
{
chkLstBx.SetItemChecked(i, false);
}
因为如果你想要在循环中添加第二行,你可能会忘记添加大括号 - 程序可能仍在编译中,并且很难找到问题。