如何在Winform的DataGridView中对数据组进行格式化?
本文关键字:数据 格式化 Winform DataGridView | 更新日期: 2023-09-27 18:19:11
在我的Winforms 4.5应用程序中,我将一个DataGridView绑定到一个名为Products的SQL Server Db表。该表有一个名为Category的列,显示产品所属的类别。例如:
C1 P11
C1 P112
C2 P21
C2 P22
C2 P23
C3 P31
.. ...
C4 P41
C4 P42
.. ...
我想设置基于每个组的DataGridView的交替行样式(不是每一行)。因此,在上面的示例中,前两行(C1组)将具有默认背景色,接下来的三行(C2组)将具有深灰色背景色,C3组的行将具有默认背景色,C4组的行将具有深灰色背景色,以此类推。我怎样才能做到这一点呢?请注意,每组中的行数将根据用户输入的数据动态变化;上面显示的演示数据并不是真实数据。
我尝试了以下两篇MSDN文章的示例,但它们不完全是我上面想要的:
- 为Windows窗体DataGridView控件设置交替行样式
- 自定义Windows窗体数据视图控件中的数据格式
编辑在真实的数据中,类别前面不会包含数字。分类的真实例子可以是:水果,蔬菜,乳制品,…
既然你知道每个类别,你可以事先为每一组定义一个颜色。否则,您需要为总数未知的组制作颜色生成器。这里有一个方法:
public static void Categorize(DataGridView dgv)
{
// Set colors for each category
Color apples = Color.Red,
bananas = Color.Yellow,
oranges = Color.Orange;
// Loop the rows
foreach (DataGridViewRow row in dgv.Rows)
{
// Read category
string category = row.Cells["GroupColumn"].Value.ToString();
// Set color according to category
switch (category)
{
case "Apple": row.DefaultCellStyle.BackColor = apples; return;
case "Banana": row.DefaultCellStyle.BackColor = bananas; return;
// If the group wasn't listed, skip
default: return;
}
}
}
不确定这将是实现您所追求的最高效的方式,但我可能会尝试根据您在这里定义的逻辑(本质上是基于组值)手动设置每行的背景颜色。它看起来像这样:
首先设置一些模拟数据:
public class DAL
{
public static DataTable GetMockData()
{
DataTable dt = new DataTable();
dt.Columns.Add("ProductId", Type.GetType("System.Int32"));
dt.Columns.Add("ProductName", Type.GetType("System.String"));
dt.Columns.Add("ProductCategory", Type.GetType("System.String"));
dt.Rows.Add(new object[] { 1, "Apple", "Fruit" });
dt.Rows.Add(new object[] { 2, "Banana", "Fruit" });
dt.Rows.Add(new object[] { 3, "Pear", "Fruit" });
dt.Rows.Add(new object[] { 4, "Potato", "Vegetable" });
dt.Rows.Add(new object[] { 5, "Celery", "Vegetable" });
dt.Rows.Add(new object[] { 6, "Carrot", "Vegetable" });
dt.Rows.Add(new object[] { 7, "Hominy", "Vegetable" });
dt.Rows.Add(new object[] { 8, "Wine", "Beverage" });
dt.AcceptChanges();
return dt;
}
}
显示将使用此数据的表单,并根据ProductCategory替换行背景颜色:
public Form1()
{
InitializeComponent();
DataTable dt = DAL.GetMockData();
this.dataGridView1.DataSource = dt;
}
private void dataGridView1_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
{
Dictionary<string, int> categoryNumber = GetUniqueCategories(sender as DataGridView);
foreach (DataGridViewRow row in dataGridView1.Rows)
{
if (row.Cells["ProductCategory"].Value != null)
row.DefaultCellStyle.BackColor = GetRowColor(categoryNumber[row.Cells["ProductCategory"].Value.ToString()]);
}
}
private Color GetRowColor(int categoryNumber)
{
if (categoryNumber % 2 == 0)
return Color.White; //default row color
else
return Color.LightGray; //alternate row color
}
private Dictionary<string, int> GetUniqueCategories(DataGridView dt)
{
int i = 0;
Dictionary<string, int> categoryNumber = new Dictionary<string, int>();
foreach (DataGridViewRow row in dt.Rows)
{
if (row.Cells["ProductCategory"].Value != null)
{
if (!categoryNumber.ContainsKey(row.Cells["ProductCategory"].Value.ToString()))
{
categoryNumber.Add(row.Cells["ProductCategory"].Value.ToString(), i);
i++;
}
}
}
return categoryNumber;
}