我们如何在Winform的DataGridView中格式化数据组

时间:2014-08-24 04:55:41

标签: c# .net winforms datagridview

在我的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文章及其示例,但它们并不是我想要的:

  1. Set Alternating Row Styles for the Windows Forms DataGridView Control
  2. Customize Data Formatting in the Windows Forms DataGridView Control
  3. 修改 在实际数据中,类别不会包含前面的数字。类别的真实例子可能是:水果,蔬菜,奶制品......

2 个答案:

答案 0 :(得分:0)

不确定这是否是实现您所追求的最高效的方式,但我可能会尝试根据您在此处定义的逻辑手动设置每行的背景颜色(主要基于团体价值)。所以可能看起来像这样:

首先设置一些模拟数据:

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;
}

答案 1 :(得分:0)

由于您了解每个类别,因此您可以预先为每个组定义颜色。否则,您需要为组生成颜色生成器,其中总计数未知。这是一种方法:

    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;
            }
        }
    }