我在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;
}
}
}
现在,我要做的是首先显示带有黄色BackColor的行(根据行背景色排序)。
答案 0 :(得分:3)
您没有有效地使用CellFormatting
事件。您会看到,此事件正在为网格的每个单元格调用。您应该检查一个特定的单元格并为其分配自定义格式。通过实施,您将重新计算每个单元格的整个网格。
这是无效的,但更重要的是,这种方法将使按底色对网格进行排序变得更加困难。格式化通常是显示数据网格的最后一步。您需要以某种方式检测事件何时在网格的每个单元中运行,然后继续对其进行排序。
您可能应该只运行一次着色循环,而不是使用CellFormatting
。如果网格是数据绑定的,则可以在DataBindingComplete
中进行操作;如果不是,则可以在初始化之后进行。
如果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是 not 数据绑定的,则应该可以使用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
后才运行此代码。
答案 1 :(得分:1)
您需要按以下方式更改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();