着色问题
您没有有效地使用CellFormatting 事件。你看,这个事件被网格的每个单元格调用。您需要检查一个特定的单元格并为其分配自定义格式。通过您的实现,您将重新计算每个单元格的整个网格。
这是无效的,但更重要的是,这种方法会使按背景颜色对网格进行排序变得更加困难。格式化通常是显示数据网格的最后一步。您需要以某种方式检测网格的每个单元格的事件何时运行,然后继续对其进行排序。
您应该只运行一次着色循环,而不是使用CellFormatting。如果您的网格是数据绑定的,您可以在 DataBindingComplete 中执行此操作,如果不是,则可以在初始化之后执行。
对数据包 DataGridView 进行排序
如果您的 datagridview 是数据绑定的,您需要对底层数据源进行排序,而不是对网格本身进行排序。也许,您需要预先计算每一行的颜色,对容器进行排序,然后才绑定 DataGridView。
有关实施思路,请参阅此问题:
更新:当您将网格绑定到数据表时,我们可以使用@TaW 在Custom 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 后运行此代码。