0

有5个目标和5名员工。每个目标都可以分配给这 5 名员工中的任意数量。因此,我为每个目标设置了 5 个 CheckBoxList,每个 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 部分,并且如果没有选择任何目标,则与该员工对应的所有复选框都未选中。请帮忙。

4

2 回答 2

0

你的代码有很多问题我会告诉你主要问题,然后我会列出你的代码的其他缺陷。

造成这种情况的原因是:

该方法存在y.Read();于 for 循环之外。因为 的功能Read();是读取数据库中的下一行。所以基本上你的代码读取第一个值,让我们假设该值将是“是”,所以它会导致 ListBox 检查员工,而不是y.Read();再次调用它,所以它不会移动到下一行!..所以该值保持“是”,并且列表中的所有复选框都将被选中。

解决方案:

就像将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++)

你的循环应该是这样的:

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表示CheckBoxListsj表示给定的项目CheckBoxList

所以它可能是这样的:

checkboxlists[z-1].Items[j-1].Selected = true;

注意:起初我并没有注意,我认为 [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++;
                    }

..祝你好运 ;)

于 2011-04-21T10:19:16.300 回答
0

一些想法:

  1. 让你的 for 循环从 0 到小于checkboxlists.Count,从 0 到小于 5。这样你就可以避免到处处理所有的减法。
  2. 在线上checkboxlists[j-1].Items[z-1].Selected = true,不应该是checkboxlists[z-1].Items[j-1].Selected = true因为我假设您正在使用 z 来迭代您的 CheckBoxLists。

它来晚了,所以我的大脑可能有点模糊,但似乎#2可能是你的问题。试一试这些想法,如果您仍有问题,我会跟进您。

于 2011-04-19T06:41:48.160 回答