【问题标题】:How to preserve DataGridView color information (both cell and text) when using column filters?使用列过滤器时如何保留 DataGridView 颜色信息(单元格和文本)?
【发布时间】:2021-07-15 20:08:51
【问题描述】:

我在我的项目中使用 AdvancedDataGridView。我可以使用右键菜单更改我想要的单元格(和文本)颜色,但是当我使用列过滤器时,所有这些颜色信息都会丢失。即使我删除了过滤器,这些颜色信息也不会回到原来的位置。 我设计了一个类,用于在打开/退出应用程序时保存/加载 DGV 颜色信息:

      public static void WriteDataGridViewSettings(System.Windows.Forms.DataGridView dgv)
    {
        XmlTextWriter writer = new XmlTextWriter(Application.StartupPath + @"\MyGridColor.xml", null);
        writer.WriteStartDocument();
        writer.WriteStartElement(dgv.Name);
        int LastRow = dgv.Rows.Count;
        for (int i = 0; i < LastRow; i++)
        {
            writer.WriteStartElement("Row");
            writer.WriteStartElement("CellColor");
            writer.WriteString(dgv.Rows[i].DefaultCellStyle.BackColor.ToArgb().ToString());
            writer.WriteEndElement();
            writer.WriteStartElement("TextColor");
            writer.WriteString(dgv.Rows[i].DefaultCellStyle.ForeColor.ToArgb().ToString());
            writer.WriteEndElement();
            writer.WriteEndElement();
        }
        writer.WriteEndElement();
        writer.WriteEndDocument();
        writer.Close();
    }

    public static void ReadDataGridViewSettings(System.Windows.Forms.DataGridView dgv)
    {
        XmlDocument xmldoc = new XmlDocument();
        XmlNodeList xmlnode;
        FileStream fs = new FileStream(Application.StartupPath + @"\MyGridColor.xml", FileMode.Open, FileAccess.Read);
        xmldoc.Load(fs);
        xmlnode = xmldoc.GetElementsByTagName("Row");
            for (int i = 0; i <= xmlnode.Count-1; i++)
            {
                int cellcolor = int.Parse(xmlnode[i].ChildNodes.Item(0).InnerText.Trim());
                int textcolor = int.Parse(xmlnode[i].ChildNodes.Item(1).InnerText.Trim());
                if (cellcolor != 0)
                {
                    dgv.Rows[i].DefaultCellStyle.BackColor = Color.FromArgb(Convert.ToInt32(cellcolor));
                    dgv.Rows[i].DefaultCellStyle.ForeColor = Color.FromArgb(Convert.ToInt32(textcolor));
                }
                else
                {
                    dgv.Rows[i].DefaultCellStyle.BackColor = Color.White;
                    dgv.Rows[i].DefaultCellStyle.ForeColor = Color.Black;
                }
            }
        fs.Close();
    }

由于上面提到的问题,我在使用滤镜退出应用后不小心丢失了颜色信息。

【问题讨论】:

  • 您使用的AdvancedDataGridView 是什么?
  • 我已经从包管理器下载了它。 DG.AdvancedDataGridView
  • 可能发生的事情是过滤器在过滤BindingSource 时重绘所有行。我建议您根据为行着色的标准,在 AdvancedDataGridView.RowPrePaint 事件中为行着色。您如何确定哪些行需要着色?我似乎只是根据它们写入文件的位置进行着色,当您开始通过过滤更改行的位置时,这显然会中断。
  • 没有为行着色的特定标准。我刚刚设计了一个右键菜单,并用它来改变我想要的行的颜色。我认为我的加载/保存颜色代码没有问题。我只需要做一些事情来避免重绘所有行。你能用代码给出你的解决方案,以便我更好地理解吗?
  • 我建议您向DataGridView 添加一个隐藏列,该列在您填充数据时为每一行分配一个唯一索引。然后,您可以存储应该着色的索引列表,并根据索引是否在列表中进行着色在RowPrePaint

标签: c# datagridview colors


【解决方案1】:

好的,这是一个可行的解决方案。您需要对其进行调整以满足您的确切要求,但它应该让您了解如何在重绘行时在 datagridview 上保持颜色。

我们的想法是我们为列表中的每一行存储一些唯一标识符,然后我们使用该标识符来决定该行是否(或什么)颜色,并将其应用于RowPrePaint 事件。

public partial class Form1 : Form
{
    BindingSource _bs = new BindingSource();
    
    //If you want to store associated colours for each row
    //expand this to whatever data structure you prefer
    List<int> _colourRows = new List<int>();

    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        //This is the normal data from, for example, a database
        DataTable table = ExampleData();

        //Now add an extra column and put some unique numbers in the datatable
        //We do it to the underlying data
        //If your data already has a unique index or sequence you don't need to do this
        table.Columns.Add("sequenceColumn", typeof(int));
        for (int i = 0; i <= table.Rows.Count - 1; i++)
        {
            table.Rows[i]["sequenceColumn"] = i;
        }

        //Bind data to the UI
        _bs.DataSource = table;
        dgv.DataSource = _bs;

        //Hide this column from UI
        dgv.Columns["sequenceColumn"].Visible = false;
        dgv.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
    }

    private void setColourToolStripMenuItem_Click(object sender, EventArgs e)
    {
        foreach (DataGridViewRow dr in dgv.SelectedRows)
        {
            //Add it to the list and also update it immediately
            _colourRows.Add((int)dr.Cells["sequenceColumn"].Value);
            dr.DefaultCellStyle.BackColor = Color.Red;
        }
    }

    private void dgv_RowPrePaint(object sender, DataGridViewRowPrePaintEventArgs e)
    {
        //The key is that this isn't the rows position index (which could change with filtering sorting)
        //It is just a value we've added to a new column for each row
        int rowColourSequence = (int)dgv.Rows[e.RowIndex].Cells["sequenceColumn"].Value;

        if (_colourRows.Contains(rowColourSequence))
        {
            dgv.Rows[e.RowIndex].DefaultCellStyle.BackColor = Color.Red;
        }
    }

    private DataTable ExampleData()
    {
        DataTable table = new DataTable();
        table.Columns.Add("Animal", typeof(string));
        table.Columns.Add("Count", typeof(int));

        table.Rows.Add("Cat", 15);
        table.Rows.Add("Dog", 10);
        table.Rows.Add("Ferret", 2);
        table.Rows.Add("Mouse", 0);

        return table;
    }
}

这里可以看到我改变排序还是过滤行颜色是否持久化:

【讨论】:

    猜你喜欢
    • 2021-12-27
    • 1970-01-01
    • 1970-01-01
    • 2014-12-30
    • 1970-01-01
    • 2020-01-23
    • 1970-01-01
    • 1970-01-01
    • 2014-10-08
    相关资源
    最近更新 更多