【问题标题】:How to sort datagridview according to row background color?如何根据行背景颜色对datagridview进行排序?
【发布时间】:2019-06-10 05:25:39
【问题描述】:

我在 WinForms (c#) 项目中有一个 DataGridView。如果满足某个条件,则对其行进行格式化。代码如下:

private void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
    foreach (DataGridViewRow Myrow in dataGridView1.Rows)
    {
        string BEFORE_HYPHEN = GetUntilOrEmpty(Convert.ToString(Myrow.Cells[2].Value));
        if (BEFORE_HYPHEN.Length == 2)
        {
        }
        else
        {
            Myrow.DefaultCellStyle.BackColor = Color.Yellow;
            Myrow.DefaultCellStyle.ForeColor = Color.Black;
        }
    }
}

现在,我要做的是让带有黄色背景颜色的行首先出现(根据行背景颜色排序)。

【问题讨论】:

  • 你用什么作为数据源?
  • 一个数据集。 dataGridView1.DataSource = DATASET_DATA.Tables[0];

标签: c# winforms datagridview


【解决方案1】:

着色问题

您没有有效地使用CellFormatting 事件。你看,这个事件被网格的每个单元格调用。您需要检查一个特定的单元格并为其分配自定义格式。通过您的实现,您将重新计算每个单元格的整个网格。

这是无效的,但更重要的是,这种方法会使按背景颜色对网格进行排序变得更加困难。格式化通常是显示数据网格的最后一步。您需要以某种方式检测网格的每个单元格的事件何时运行,然后继续对其进行排序。

您应该只运行一次着色循环,而不是使用CellFormatting。如果您的网格是数据绑定的,您可以在 DataBindingComplete 中执行此操作,如果不是,则可以在初始化之后执行。

对数据包 DataGridView 进行排序

如果您的 datagridview 是数据绑定的,您需要对底层数据源进行排序,而不是对网格本身进行排序。也许,您需要预先计算每一行的颜色,对容器进行排序,然后才绑定 DataGridView。

有关实施思路,请参阅此问题:

更新:当您将网格绑定到数据表时,我们可以使用@TaWCustom sorting order - DataGridView 中发布的代码作为起点。

这是一个简单的例子:

//we'll need to process this table
var table = DATASET_DATA.Tables[0];

//First, add a column for BackColor and calculate values
//Here I use a simple column of type Color and default order (alphabetically, by color name)
//If you need a more complicated sorting, consider creating a numeric (BackColorOrder) column instead
table.Columns.Add("BackColor", typeof(Color));
foreach (DataRow row in table.Rows)
{
    string BEFORE_HYPHEN = GetUntilOrEmpty(Convert.ToString(row[2]));
    if (BEFORE_HYPHEN.Length == 2)
    {
        //white, or whatever your default color is
        row["BackColor"] = Color.White;
    }
    else
    {
        row["BackColor"] = Color.Yellow;
    }
}

//Assign a sorted binding source as a datasource
var bs = new BindingSource
{
    DataSource = table,
    Sort = "BackColor ASC"
};
dataGridView1.DataSource = bs;
//Hide backcolor from the grid
//If this column has a meaning in your application (some kind of a status?)
//Consider displaying it, so the user will be able to change sort order
dataGridView1.Columns["BackColor"].Visible = false;

...

/// <summary>
/// We're using DataBindingComplete to calculate color for all rows
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void dataGridView1_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
{
     //Assign a pre-calculated BackColor for grid rows
     foreach (DataGridViewRow row in dataGridView1.Rows)
     {
          row.DefaultCellStyle.BackColor = (Color)row.Cells["BackColor"].Value;
     }
}

这是full, runnable example。结果如下所示:

对非数据绑定的 DataGridView 进行排序

如果你的datagridview不是数据绑定的,你应该可以使用Sort(IComparer comparer)对其进行排序:

dataGridView1.Sort(new BackColorComparer());

...
/// <summary>
/// Custom comparer will sort rows by backcolor
/// </summary>
private class BackColorComparer : System.Collections.IComparer
{
     public int Compare(object x, object y)
     {
          var row1 = (DataGridViewRow)x;
          var row2 = (DataGridViewRow)y;
          //Sorting by color names, replace with custom logic, if necessary
          return string.Compare(
               row1.DefaultCellStyle.BackColor.ToString(),
               row2.DefaultCellStyle.BackColor.ToString());
     }
}

确保仅在为所有行计算完 BackColor 后运行此代码。

【讨论】:

  • 另外,dataGridView1.DataSource = DATASET_DATA.Tables[0]; 是我绑定 DataGridView 的方式。请问我可以有一个 POC 类型 sn-p 吗?
  • @theLuckyOne 另一个更新,现在有一个完整的、可运行的代码 sn-p
【解决方案2】:

您需要将 datagridview 数据源更改如下:

var sorted = DATASET_DATA.Tables[0].Select().OrderBy(row =>
{
    string BEFORE_HYPHEN = GetUntilOrEmpty(Convert.ToString(row.ItemArray[2]));
    return BEFORE_HYPHEN.Length == 2;
});
dataGridView1.DataSource = sorted.CopyToDataTable(); 

【讨论】:

    猜你喜欢
    • 2016-11-13
    • 1970-01-01
    • 2014-07-04
    • 2014-08-06
    • 1970-01-01
    • 1970-01-01
    • 2020-01-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多