有5个目标和5个员工。每个目标都可以分配给这5名员工中的任意一个。所以我为每个目标都有5个CheckBoxLists,每个CheckBoxList都有这5个员工的名字作为项目。
我想从数据库中检索哪些员工已分配了哪些目标。我有以下代码:
List<CheckBoxList> checkboxlists = new List<CheckBoxList>();
checkboxlists.Add(CheckBoxList1);
checkboxlists.Add(CheckBoxList2);
checkboxlists.Add(CheckBoxList3);
checkboxlists.Add(CheckBoxList4);
checkboxlists.Add(CheckBoxList5);
for (int z = 1; z <= checkboxlists.Count; z++)
{
SqlCommand check = new SqlCommand("SELECT ISGoal1, ISGoal2,ISGoal3, ISGoal4,ISGoal5 FROM PRM2011_EMPLOYEE_GOAL WHERE EmployeeID = '" + employeeid[z - 1] + "'", con);
SqlDataReader y = check.ExecuteReader();
y.Read();
for (int j = 1; j <= 5; j++)
{
if (null != y && y.HasRows)
{
string yes_or_no = y["ISGoal" + j].ToString().Trim();
if (yes_or_no == "Yes")
{
checkboxlists[j-1].Items[z-1].Selected = true;
}
//else checkboxlists[j - 1].Items[z - 1].Selected = false;
}
}
y.Close();
}
我的问题是,即使我为员工选择了一个目标,也会选择与该特定员工相对应的所有复选框。为什么会这样?
相应地,如果我在发布的代码中注释掉了else部分,并且如果未选择任何目标,那么与该雇员相对应的所有复选框都将被取消选中。请帮忙。
答案 0 :(得分:0)
一些想法:
checkboxlists.Count
,从0变为小于5.这样你就可以避免在任何地方处理所有减法。checkboxlists[j-1].Items[z-1].Selected = true
行上,不应该是checkboxlists[z-1].Items[j-1].Selected = true
,因为我假设您使用z来迭代CheckBoxLists。它在这里很晚,所以我的大脑可能有点模糊,但似乎#2可能是你的问题。如果你还有问题我会跟进你。
答案 1 :(得分:0)
您的代码中有很多问题我会告诉您主要问题,然后我会列出您代码的其他缺陷。
for循环的方法y.Read();
的存在。
因为Read();
的功能是读取数据库中的下一行。所以基本上你的代码读取第一个值,让我们假设值为“是”,这样它将导致ListBox检查员工,而不是再次调用y.Read();
,所以它移动到它没有的下一行! ..因此值保持为“是”,并且将检查列表中的所有CheckBox。
解决方案:
只需将y.Read();
从循环外侧移入其中即可。
像这样:
List<CheckBoxList> checkboxlists = new List<CheckBoxList>();
checkboxlists.Add(CheckBoxList1);
checkboxlists.Add(CheckBoxList2);
checkboxlists.Add(CheckBoxList3);
checkboxlists.Add(CheckBoxList4);
checkboxlists.Add(CheckBoxList5);
for (int z = 1; z <= checkboxlists.Count; z++)
{
SqlCommand check = new SqlCommand("SELECT ISGoal1, ISGoal2,ISGoal3, ISGoal4,ISGoal5 FROM PRM2011_EMPLOYEE_GOAL WHERE EmployeeID = '" + employeeid[z - 1] + "'", con);
SqlDataReader y = check.ExecuteReader();
for (int j = 1; j <= 5; j++)
{
y.Read();
if (null != y && y.HasRows)
{
string yes_or_no = y["ISGoal" + j].ToString().Trim();
if (yes_or_no == "Yes")
{
checkboxlists[j-1].Items[z-1].Selected = true;
}
//else checkboxlists[j - 1].Items[z - 1].Selected = false;
}
}
y.Close();
}
首先
您需要修改SqlCommand
以使用SqlParameters
SqlCommand check = new SqlCommand("SELECT ISGoal1, ISGoal2,ISGoal3, ISGoal4,ISGoal5 FROM PRM2011_EMPLOYEE_GOAL WHERE EmployeeID = @EmpID", con);
check.Parameters.AddWithValue("@ImpID", employeeid[z - 1]);
<强>第二强>
如果您正在尝试构建一个真正的应用程序,那么这是一个非常糟糕的做法。即使您没有真正构建此应用程序,我也不认为这是练习方式。
for (int j = 1; j <= 5; j++)
你的Loop应该是这样的:
for (int j = 1; j <= checkboxlists.Count; j++)
<强>第三强>
使用字符串表示“是/否”值也是一种不好的做法。您应该使用所有ISGoal
列数据库,即DataType BIT
。因此,您将C#代码中的局部变量DateType从string
更改为bool
。
<强>四强>
checkboxlists[j-1].Items[z-1].Selected = true;
你应该像Ryan所说的那样切换,因为z
表示CheckBoxLists
而j
表示给定CheckBoxList
的项目
所以它可能是这样的:
checkboxlists[z-1].Items[j-1].Selected = true;
N.B:我一开始并没注意到我认为[z-1]是某种LINQ表达式:D !! ..这是我的错,但我的意思是我在第一次开始编程的时候曾经这样做过,我仍然无法识别它......这不是我认为最好的做法! ..我的建议尊重使用的基于零的编号。
<强>最后强>
如果y.Read();您不必每次都检查是或否。所以我认为这段代码会更有意义,并且硬编码循环的条件是一个非常糟糕的做法,所以我们将使用while循环并添加int类型的局部变量,然后我们将在我们的内部增加它循环代码,以便您可以使用它来访问CheckBoxList项
int j = 1;
while (y.Read())
{
string yes_or_no = y["ISGoal" + j].ToString().Trim();
if (yes_or_no == "Yes")
{
checkboxlists[j-1].Items[z-1].Selected = true;
//use our counter "j" here
}
//else checkboxlists[j - 1].Items[z - 1].Selected = false;
//use our counter "j" here
j++;
}
..祝你好运;)