【问题标题】:How can i change datagridview specific checkbox cell color and check based on database value?如何更改 datagridview 特定的复选框单元格颜色并根据数据库值进行检查?
【发布时间】:2022-01-19 21:13:42
【问题描述】:

我有一个带有复选框列的数据网格视图。复选框单元格应根据数据库表列中的特定值更改颜色并检查状态。如果该值为“grafcheck”,则复选框单元格和复选框应为绿色并选中。如果表中的字段为空,则复选框单元格应为白色且未选中。 下面的代码做了它应该做的,但它标记为每个复选框都被选中,并且无论值是否存在,它们都变成绿色。

using (SqlConnection con = new SqlConnection(@"Data Source=GAMEWORK\SQLEXPRESS;Initial Catalog=Tida;Integrated Security=True"));
            {

                DataGridViewCellStyle style = new DataGridViewCellStyle();
                style.BackColor = Color.Green;
                style.ForeColor = Color.White;

                string sql = "SELECT GraficaFinal FROM Comenzi WHERE GraficaFinal='grafcheck'";
                con.Open();
                SqlCommand cmd = new SqlCommand(sql, con);
                SqlDataReader reader = cmd.ExecuteReader();
                
                if (reader.HasRows)
                {
                    while (reader.Read())
                    {
                        string graph = reader["GraficaFinal"].ToString();

                        for (int i = 0; i < ComNef.Rows.Count; i++)
                        {
                                if (graph == "grafcheck")
                                {
                                    ComNef.Rows[i].Cells["chkbxGrafica"].Value = true;
                                    ComNef.Rows[i].Cells["chkbxGrafica"].Style = style;
                                }

                                else if (graph == "")
                                {
                                    ComNef.Rows[i].Cells["chkbxGrafica"].Value = false;
                                    ComNef.Rows[i].Cells["chkbxGrafica"].Style.BackColor = Color.White;
                                }

                        }
                        
                    }

                }
                con.Close();
            }

【问题讨论】:

标签: c# sql datagridview


【解决方案1】:

您可能想在这里重新考虑您的方法。首先你说代码运行后,所有的复选框都被选中并且是绿色的。据我所知,这是有道理的,因为查询只获取行……… WHERE GraficaFinal='grafcheck'……所以如果你从查询中获取数据……那么所有行都会有grafcheck。这几乎使……if (graph == "grafcheck") { ..……声明变得多余了。

另一个问题……,while (reader.Read()) { ………循环正在遍历读取的行,所以代码读取一行,然后设置graph变量……

string graph = reader["GraficaFinal"].ToString();

这很好......但是......然后代码(出于某种未知原因)“循环”通过网格中的所有行......? ……这不可能。基本上,当使用for 循环遍历网格的行时会发生什么情况,会将每行复选框状态设置为“当前”行graph 值......不管GraficaFinal 单元格中的实际值是什么在那一行。但是我们已经知道它将是“grafcheck”。

如果您跟踪此代码,它将基本上将所有复选框值和颜色设置为数据中最后一行包含的任何内容。换句话说......我相信你不希望在那里有一个for 循环,你只会在该行中设置一 (1) 个值。这就引出了“为什么”代码“手动”将值添加到网格中?我相信您可以使用DataTable 并直接从查询中填写。然后您可以简单地将DataTable 用作网格的DataSource。填写表格的代码可能类似于……

DataTable GridDT = new DataTable(“Comenzi”);
GridDT.Load(reader);

这将根据您的查询用一列GraficalFinal 数据填充表格。

另外……目前还不清楚ComNef 网格中的chkbxGrafica 列来自“哪里”……我假设您在设计器中添加该列,或者可能在一些未显示的代码中添加该列。如果您要手动将列添加到显示的 GRID 中,那么有一种更简单的方法。

建议您手动将列添加到我们之前从数据库查询中获得的DataTable,而不是手动将列添加到 GRID。这对于将列添加到 GRID 还是 TABLE 可能显得微不足道……但是,GRID 列无法在其列中使用“表达式”。 DataTable 允许列包含“表达式”……

DataColumn.Expression Property

如果我们想将chkbxGrafica 单元格设置为选中或未选中状态,这将非常方便。这个表达式可能看起来像……

"IIF(GraficalFinal = 'grafcheck', 'true', 'false')"

这将“自动”将复选框单元格设置为正确的选中状态。注意……因为复选框列是“表达式”列……那么用户将无法直接更改复选框状态,但是……更改GraficaFinal 单元格将更改复选框状态。 “表达式”列的这一简单代码将消除所有循环通过网格并设置复选框值的代码。

此外...一旦代码运行并且用户将GraficalFinal单元格值“更改”为grafcheck以外的任何值...然后...该行上的复选框将自动变为“未选中”。显然,如果单元格值为“grafcheck”,那么这会将复选框设置为“checked”

不幸的是,这不会像你想要的那样给单元格“着色”。为此,我们将需要查看 GRID。 Ňɏssa Pøngjǣrdenlarp 评论了一个链接,它是为网格单元着色的许多可能方法之一。更改单元格颜色的最常见和最直观的网格事件是网格CellFormatting 事件。当需要对单元格进行格式化时,将触发此事件,在这种情况下,我们可以简单地检查复选框值是什么,然后对其进行适当的着色。

请注意……使用网格CellFormatting 事件效果很好,但是,如果您将Debug 语句放入事件中……您会注意到该事件将触发比需要的次数多得多的次数。例如,当用户简单地将光标移动到网格中的单元格上时,它可能会触发。这是我可能会选择不同事件的原因之一,例如网格CellValueChanged 事件。

不幸的是,这为更多工作​​打开了大门,因为在设置网格DataSource 时不会触发该事件。 CellFormatting 事件将在设置网格DataSource 时触发。所以......如果我们使用网格CellValueChanged 事件而不是网格CellFormatting 事件......那么......我们最终会陷入我们已经在同一条船上......我们将需要实现添加代码以“循环”所有网格中的行并在设置网格DataSource 后立即设置单元格颜色。当然,这消除了单元格在不需要时被格式化,但是,它为您创造了更多的工作。在下面的示例中……我将使用网格CellFormatting 事件。

所以……总而言之……在DataTable 中添加一个带有“表达式”的布尔类型列。这将根据GraficalFinal 单元格包含的内容设置复选框值。然后连接网格CellFormatting 事件以设置单元格颜色。

下面的代码演示了上述内容的一个小而完整的示例。注意...显然GetDataFromDB 方法只是创建一个带有一些随机值的单列表,您可以更改此代码以从数据库中获取GraficaFinal 表。如果您将DataGridView 放到一个表单上并连接它的CellFormatting 事件,那么下面是代码应该产生的内容。祝你好运。

DataTable GridDT;
DataGridViewCellStyle CheckedStyle;
DataGridViewCellStyle UnCheckedStyle;

public Form1() {
  InitializeComponent();
  CheckedStyle = new DataGridViewCellStyle();
  UnCheckedStyle = new DataGridViewCellStyle();
  CheckedStyle.BackColor = Color.Green;
  CheckedStyle.ForeColor = Color.White;
  UnCheckedStyle.BackColor = Color.White;
  UnCheckedStyle.ForeColor = Color.Black;
}

private void Form1_Load(object sender, EventArgs e) {
  GridDT = GetDatFromDB();
  AddCheckBoxColumnToTable(GridDT);
  dataGridView1.DataSource = GridDT;
}

private DataTable GetDatFromDB() {
  DataTable dt = new DataTable();
  dt.Columns.Add("GraficalFinal", typeof(string));
  Random rand = new Random();
  for (int i = 0; i < 10; i++) {
    if (rand.Next(2) == 0) {
      dt.Rows.Add("grafcheck");
    }
    else {
      dt.Rows.Add("");
    }
  }
  return dt;
}

private void AddCheckBoxColumnToTable(DataTable dt) {
  DataColumn col = new DataColumn("chkBxGrafica", typeof(bool), "IIF(GraficalFinal = 'grafcheck', 'true', 'false')");
  dt.Columns.Add(col);
}

private void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e) {
  if (e.ColumnIndex == 1) {
    if (!dataGridView1.Rows[e.RowIndex].IsNewRow) {
      //Debug.WriteLine("DGV_CellFormatting <- Enter");
      if ((bool)dataGridView1.Rows[e.RowIndex].Cells[1].Value == true) {
        dataGridView1.Rows[e.RowIndex].Cells[1].Style = CheckedStyle;
      }
      else {
        dataGridView1.Rows[e.RowIndex].Cells[1].Style = UnCheckedStyle;
      }
      //Debug.WriteLine("DGV_CellFormatting -> Leave");
    }
  }
}

【讨论】:

  • 哇...这是一个非常复杂的答案。太感谢了!没关系,做它应该做的,但我不想添加任何列,因为我已经有了它们(大约 11 个)。其中之一是复选框列,它是由代码而非设计器生成的。我想要的是,当数据库表中存在值“grafcheck”时,复选框变为选中并变为绿色。就像你发布的照片​​一样。代码中的数据表会删除 datagridview 中的所有列并插入新列。
  • 很抱歉没有提到这一点。我设法做到了,我修改了你的代码。我只是隐藏了其他列并添加了我的原始数据表。你真的救了我!
猜你喜欢
  • 2023-04-06
  • 1970-01-01
  • 2017-02-05
  • 1970-01-01
  • 1970-01-01
  • 2017-08-02
  • 2015-06-11
  • 2013-10-23
相关资源
最近更新 更多