首页 > 解决方案 > 根据excel表上的值获取单元格范围/位置并在c#中为单元格datagridview着色

问题描述

我在数据网格视图中显示导入的 excel 表。根据行名,我正在替换特定的单元格字符串。现在我想根据它们的值为特定的单元格着色。

 private void Replace_strings()
    {
        TextInfo textInfo = new CultureInfo("en-US", false).TextInfo;
        DataTable dt = dataGridView1.DataSource as DataTable;

        foreach (DataRow r in dt.Select("[SET 1] = 'First Name'"))
            for (int y = 1; y < r.ItemArray.Length; y++)
            {
                String str = r[y].ToString();
                r[y] = str.Replace('0', 'o');
                r[y] = textInfo.ToUpper(r[y].ToString());

                if (r[y].ToString().Contains("%"))
                {

                   //If a cell contains "%"I want to mark that cell in red colour
                  //CellStyle.BackColor = Color.Red;
                    //CellStyle.ForeColor = Color.White;


                }

            }
    }

我如何有效地纠正这个

预期的

点击查看预期输出图像

标签: c#exceldatagridviewcelldatagridviewcellstyle

解决方案


有很多方法可以做到这一点。我会遍历“网格”而不是数据源。DataTable包含数据,但是“网格”显示它。因此,您要更改颜色的是“网格”而不是数据表。

但是,如果您连接了几个网格事件,则可能不需要循环遍历网格。

网格有许多您可以使用的“CellFormatting/Painting”事件,但是,您要小心使用哪一个。这些事件中的大多数经常被触发,即使单元格值没有改变。换句话说,如果网格因为滚动而被重新绘制,那么重新格式化单元格是一种浪费,因为它没有改变。

鉴于此,我建议您连接两 (2) 个网格事件……CellEndEdit事件……当单元格值更改并且用户尝试离开单元格时,将触发此事件。当此事件触发时,代码应查找“%”并相应地格式化。

CellEndEdit当网格加载数据“之后”进行更改时,该事件将起作用。不幸的是,CellEndEdit当数据“最初”加载到网格中时,该事件不会触发。为了提供帮助,使用了第二个事件,RowsAdded当“新”行添加到网格时将触发此事件。在这种情况下,我们可以循环遍历行中的每个单元格并相应地设置颜色。

例子……</p>

将两个事件连接起来……</p>

public Form1() {
  InitializeComponent();
  dataGridView1.CellEndEdit += new DataGridViewCellEventHandler(dataGridView1_CellEndEdit);
  dataGridView1.RowsAdded += new DataGridViewRowsAddedEventHandler(dataGridView1_RowsAdded);
}

因为我们需要“独立地”格式化单元格,所以创建一个方法是有意义的,这样给定一个DataGridViewCell方法将检查单元格的值并相应地格式化它。这种方法在这两种情况下都会派上用场。该方法可能看起来像……</p>

private void FormatACell(DataGridViewCell cell) {
  if (cell.Value != null && cell.Value.ToString().Contains("%")) {
    cell.Style.BackColor = Color.Red;
  }
  else {
    cell.Style.BackColor = Color.White;
  }
}

接下来是两个事件……</p>

private void dataGridView1_RowsAdded(object sender, DataGridViewRowsAddedEventArgs e) {
  DataGridViewRow row = dataGridView1.Rows[e.RowIndex];
  foreach (DataGridViewCell cell in row.Cells) {
    FormatACell(cell);
  }
}

private void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e) {
  DataGridViewCell cell = dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex];
  FormatACell(cell);
}

最后,完成示例……</p>

DataTable dt;

private void Form1_Load(object sender, EventArgs e) {
  dt = GetDataFromDB();
  dataGridView1.DataSource = dt;
}

private DataTable GetDataFromDB() {
  DataTable dt = new DataTable();
  dt.Columns.Add("Col1", typeof(string));
  dt.Columns.Add("Col2", typeof(string));
  dt.Columns.Add("Col3", typeof(string));
  dt.Rows.Add("Data1", "Dat%a2", "Data3");
  dt.Rows.Add("Data2%", "Data3", "Data1");
  dt.Rows.Add("Data3", "Data2", "Da%ta1");
  return dt;
}

推荐阅读