使用一个标识字段将多个按钮文本设置为数据库中的字段

时间:2016-03-20 19:25:07

标签: c# sql database loops ms-access

我一整天都在努力解决这个问题,最终认为我无法解决这个问题:)

因此,从内存循环到数据库中的记录通常就像这样...(我认为)

while(reader.Read())
{
    btn.Text = reader["Field Name"].ToString();
    btn2.Text = reader["Field Name"].ToString();
}

我认为这会将第一个字段文本写入第一个按钮,然后将下一个字段名称写入下一个按钮。相反,它将最后一个字段内容写入所有按钮。

我试图按顺序将4个字段内容从4个记录写入4个按钮,因此button1 =记录(行)1字段,button2 = record2字段等...

这是原始代码:

private void Homework_Load(object sender, EventArgs e)
{
    try
    {
        connection.Open();
        OleDbCommand command = new OleDbCommand();
        command.Connection = connection;
        command.CommandText = "SELECT COUNT(*) FROM HWTasks WHERE TwyID = '" + Login.TwyIDRetrieve + "'";
        int OccuranceNo = 0;
        OccuranceNo = (Int32)command.ExecuteScalar();
        command.Dispose();
        command.Connection = connection;
        command.CommandText = "SELECT * FROM HWTasks WHERE TwyID = '" + Login.TwyIDRetrieve + "'";
        OleDbDataReader reader = command.ExecuteReader();

        if (OccuranceNo == 1)
        {
            while (reader.Read())
            {
                HwTskBtn1.Text = reader["TaskName"].ToString();
            }
        }
        else if (OccuranceNo == 2)
        {
            while (reader.Read())
            {
                HwTskBtn1.Text = reader["TaskName"].ToString();
                HwTskBtn2.Text = reader["TaskName"].ToString();
            }
        }
        else if (OccuranceNo == 3)
        {
            while (reader.Read())
            {
                HwTskBtn1.Text = reader["TaskName"].ToString();
                HwTskBtn2.Text = reader["TaskName"].ToString();
                HwTskBtn3.Text = reader["TaskName"].ToString();
            }
        }
        else if (OccuranceNo == 4)
        {
            while (reader.Read())
            {
                HwTskBtn1.Text = reader["TaskName"].ToString();
                HwTskBtn2.Text = reader["TaskName"].ToString();
                HwTskBtn3.Text = reader["TaskName"].ToString();
                HwTskBtn4.Text = reader["TaskName"].ToString();
            }
        }

但首先尝试了这个:

while (reader.Read())
{
    if (OccuranceNo == 1)
    {
        HwTskBtn1.Text = reader["TaskName"].ToString();
    }
    else if (OccuranceNo == 2)
    {
        HwTskBtn1.Text = reader["TaskName"].ToString();
        HwTskBtn2.Text = reader["TaskName"].ToString();
    }
    else if (OccuranceNo == 3)
    {
        HwTskBtn1.Text = reader["TaskName"].ToString();
        HwTskBtn2.Text = reader["TaskName"].ToString();
        HwTskBtn3.Text = reader["TaskName"].ToString();
    }
    else if (OccuranceNo == 4)
    {
        HwTskBtn1.Text = reader["TaskName"].ToString();
        HwTskBtn2.Text = reader["TaskName"].ToString();
        HwTskBtn3.Text = reader["TaskName"].ToString();
        HwTskBtn4.Text = reader["TaskName"].ToString();
    }
    else if (OccuranceNo > 4)
    {
        MessageBox.Show("Error: There are more than 4 homework tasks set for your account, contact your teacher/administrator to resolve/nTasks set out of expected range!", "Oops!");
    }
}

感谢任何可以帮助我的人! 利安

2 个答案:

答案 0 :(得分:2)

我不想给出一个确切的答案(这很容易),但更多的是试图让你理解一切是如何运作的。你说:

  

我认为这会将第一个字段文本写入第一个按钮,然后将下一个字段名称写入下一个按钮。

那是错的。

当您拥有OleDbDataReader变量时,Read()会从当前行分配字段并将内部光标前进到下一行(如果有的话)。如果实际上有任何行要读取,它也会返回true,如果它在最后,则返回false

所以让我们尝试编写这个循环:

while(reader.Read())
{
    btn.Text = reader["Field Name"].ToString();
    btn2.Text = reader["Field Name"].ToString();
}

以更明智的方式和评论:

bool thereAreMoreRows = reader.Read(); // We read the first row, if it exists
                                       // thereAreMoreRows contains true
                                       // if we read a row, or false if
                                       // we didn't

while(thereAreMoreRows)  // Repeat what is inside the { } while the 
                         // variable thereAreMoreRows is true
                         // Don't enter if it was false
{
   btn.Text = reader["Field Name"].ToString(); // Assign the current row's "Field Name"
                                               // converted to a string to the button "btn" text property

   btn2.Text = reader["Field Name"].ToString(); // Assign the current row's "Field Name" 
                                                // converted to a string to the button "btn2" text property. 
                                                // Note that this is the same we assigned to btn!

   thereAreMoreRows = reader.Read(); // Advance to the next row, and read it
                                     // or set thereAreMoreRows to false if
                                     // there were no more rows

} // Repeat until thereAreMoreRows is false

因此,如果您遵循逻辑,两个按钮将包含相同的文本,以及最后一行"字段名称"的那些按钮,这正是发生在您身上的事情。

  

相反,它会将最后一个字段内容写入所有按钮。

尝试按照代码的作用进行操作,应该很容易推断出你的代码,以及如何解决它。

我不想给出解决方案,但只是告诉你错误和原因。

编写代码非常详细,以便逐行理解...一旦理解了它,如果你理解了全局图片,它就很容易重构和优化它。你的最终循环代码只能写成3行,但是如果你不能理解他们在做什么,就没有必要给你这三行。

更新,因为在您的回答中,我的回答似乎有效,您现在正走在正确的轨道上,让我们看看如何让您的循环更好并且执行正如您在初始代码中所期望的那样。

你可以忽略整个OccuranceNo,它只是任务的数量。由于您具有非动态UI,因此要显示的最大任务数(在按钮上)为4,但您可以减少。

因此,让我们将这些按钮放在我们可以通过索引引用的数组中:

var myButtons = new Button[] { HwTaskBtn1, HwTaskBtn2, HwTaskBtn3, HwTaskBtn4 };
var index = 0;
// either we're up to the 4th index, or there are no more tasks
while(index < 4 && reader.Read())
   myButtons[index++].Text = reader["TaskName"].ToString();

现在应该很容易弄清楚代码的作用,同时仍然清晰可读(请注意,因为while块只有一行,所以可以删除括号{}

你的答案中的问题(这个问题解决了)是:

  1. 您假设数据库中只有4条记录。如果超过4,您的代码将抛出异常(因为它会尝试写入taskName[4],这超出范围)。
  2. 如果行数少于4行,您的按钮仍会被分配一个文本(我也不会更改未更新按钮的文本,因此这可能对您有用)。
  3. 否则,你的回答是一种方法,你肯定是正确的。

    应该指定详细信息(当没有任务时,如何处理其他按钮,如果有超过4个任务我们应该显示错误,是否应该隐藏未分配的按钮等),但那是什么规格: - )

答案 1 :(得分:0)

通过使用数组创建了一个解决方案,这让我创建了一个原子和微小的循环,与我上面的尴尬相比:) @Jcl我确定这不是你想要的解决方案和我“我相信你可以提供更好的方法,但如果这种方法有效,那么从技术上讲它是一个正确的答案吗? ;)

阵列:

//count value to step through array
int count = 0;
//array to store row data
string[] taskName = new string[4];

循环然后分配:

            while (reader.Read())
            {
                //Assigns array point from count variable, reads data from row into array point
                taskName[count] = reader["TaskName"].ToString();
                //counts up the point in the array
                count++;
            }
            HwTskBtn1.Text = taskName[0];
            HwTskBtn2.Text = taskName[1];
            HwTskBtn3.Text = taskName[2];
            HwTskBtn4.Text = taskName[3];