【问题标题】:Can't update datagridview and form elements in C#无法在 C# 中更新 datagridview 和表单元素
【发布时间】:2014-11-12 02:48:40
【问题描述】:

在使用 Visual Studio Express 2013 的 C# 中,我正在尝试从事件处理程序更新 datagridview 以进行按钮单击。该按钮是一个提交按钮,用于更新 Sqlite 数据库,然后更新 datagridview 以反映更改。问题是,在我更新 Sqlite 数据库(更新成功)后,datagridview 不会从事件处理程序更新(这是在 getLoggedData(employeeNumber, false) 参考中设置的)。 (我也尝试更新一个没有更新的文本框)。在 datagridview 应该更新之后,我添加了一个 thread.sleep,因此用户可以看到在 datagridview 重置之前所做的更改(单击按钮最后一行的 getLoggedData() 会重置 datagridview)。

getLoggedData(employeeNumber, false) 方法只是获取 sqlite 数据库作为数据表并将其设置为 dgvLogged 的​​数据源。检查列和 addRow 应该与问题无关。

附带说明,我已经尝试使用绑定源,但无济于事。

// This is when the button submit is clicked
private void btnConfirmEntry_Click(object sender, EventArgs e)
    {
        modifyEmployeeJobs();

        getLoggedData(employeeNumber, false);
        Thread.Sleep(2000);

        getLoggedData();
    }

public void getLoggedData(string empID, bool addRow)
    {
        dgvColumnNumberAdder = 1; // Adds a 1 to the index if the checkboxes are present in the datagridview
        MySql sql = new MySql();
        try
        {
            dgvLogged.Columns.Clear();

            DataGridViewCheckBoxColumn checkColumn = new DataGridViewCheckBoxColumn();
            checkColumn.Name = "Check";
            checkColumn.HeaderText = "";
            checkColumn.Width = 50;
            checkColumn.ReadOnly = false;
            checkColumn.FillWeight = 10; //if the datagridview is resized (on form resize) the checkbox won't take up too much; value is relative to the other columns' fill values
            checkColumn.MinimumWidth = 30;
            dgvLogged.Columns.Add(checkColumn);

            DataTable dt = sql.getLoggedData(empID);

            if (addRow)
            {
                // Add row to datatable for job information that was just received
                DataRow row;
                row = dt.NewRow();
                row["EmpID"] = employeeNumber;
                row["Job"] = jobNumber;
                row["WorkCode"] = workCode;
                row["JobState"] = "Pending";

                dt.Rows.Add(row);
            }                

            dgvLogged.DataSource = dt;
            dgvLogged.Columns[jobTrackingColumnNumbers["ID"] + dgvColumnNumberAdder].Visible = false;
            setCheckStates();
            dgvLogged.Visible = true;
            txtInstructions.Visible = false;
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.ToString());
        }
    }

【问题讨论】:

  • 您不想让线程在 UI 中休眠 - 如果您希望用户能够导航 2 秒(这不是很多时间)启动一个计时器,该计时器将做同样的逻辑,然后做你打算做的事情。在该按钮调用中休眠将锁定 UI。你最后一次调用 getLoggedData() 调用了一个没有参数的方法——那个方法在哪里?
  • 添加计时器而不是线程睡眠效果很好。如果我在给出 thread.sleep() 命令之前告诉 datagridview 更新,为什么将 UI 保持 2 秒会阻止 datagridview 更新?
  • 因为 UI 线程仍在运行,并且您将其休眠,因此您正在等待该休眠完成(在该线程上),然后再进行下一步,即重新绑定数据。我想不出任何理由在 UI 线程上休眠,UI 仅用于显示,因此您希望通过事件和调用触发对其的更新。请记住,即使您不管理这些线程,表单也是一个多线程环境。
  • 我将我的回答合并为一个答案。

标签: c#


【解决方案1】:

问题正在发生,因为您在 UI 按钮事件上执行 Thread.Sleep() - 这会锁定按钮事件发生的线程,直到睡眠完成。

您不想让线程在 UI 中休眠。如果您希望用户能够导航 2 秒,您可以启动 System.Timer,在经过时完成您想要执行的其余逻辑。在该按钮调用中休眠将锁定 UI,因为 UI 线程仍在运行,并且您将其休眠,因此您正在等待该休眠完成(在该线程上),然后再进行下一步,即重新绑定数据。

我想不出在 UI 线程上休眠的任何理由,UI 仅用于显示,因此您希望通过事件和调用触发对其的更新。请记住,即使您不管理这些线程,表单也是一个多线程环境。

【讨论】:

  • 您是说 datagridview 更新发生在 UI 线程之外的线程上,并且 UI 线程在单击事件例程完成之前不会完成执行?我想我还是不明白,你说数据重新绑定发生在thread.sleep()之后,但是在我的代码中,数据源是先更新的,然后才发生thread.sleep()。
  • 不过,从我的其他评论来看,您没有显示 getLoggedData() 方法-我的猜测是这是一个有效的方法,并且会进行您想要的更新(然后在睡眠发生后看到)。至于 UI 对象的线程管理,我不知道——我只知道它们在不同的线程上,你应该调用它们。我尽量不要弄乱 Visual Studio 自动生成的东西(除了设计器部分)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-10-25
  • 1970-01-01
  • 1970-01-01
  • 2015-05-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多