How to detect styling applied to DataGridView via e.CellStyle.BackColor in the CellFormatting event?

StackOverflow https://stackoverflow.com/questions/10604517

سؤال

If we've applied styling (e.CellStyle.BackColor say) to some rows via the CellFormatting event of a DataGridView, is it then possible to detect that styling at a later stage?

For example, currently we use a generic bloc of code to handle printing and exporting to Excel for any and all our DataGridViews. Until now the code hasn't catered for any styling.

So we want to add it in.

If we check the .DefaultCellStyle of the row or cell then our styling doesn't show up (it just shows as 0 or Black, which is completely wrong).

I assume that's because we've applied the styling via a CellFormatting event, instead of embedding it into the DefaultCellStyle.

هل كانت مفيدة؟

المحلول

Unfortunately I could not find a complete solution to your issue, only a work around.

Some experimenting with the CellFormatting event using the example from MSDN resulted in me seeing exactly what you were seeing - the BackColor was clearly being set but the CellStyle was not reflecting that. 1

The work around I found was to not use the DataGridViewCellFormattingEventArgs CellStyle property but to instead go straight to the grid. This has the downside that you now need to manually handle the case where you do not want to format the cell.

I've got some code below showing this - it is again just modifying the MSDN code:

void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
    // If the column is the Artist column, check the
    // value.
    if (this.dataGridView1.Columns[e.ColumnIndex].Name == "Artist")
    {
        if (e.Value != null)
        {
            // Check for the string "pink" in the cell.
            string stringValue = (string)e.Value;
            stringValue = stringValue.ToLower();
            if ((stringValue.IndexOf("pink") > -1))
            {
                // With the commented line below we cannot access the new style
                //e.CellStyle.BackColor = Color.Pink;                    

                // With this line we can!
                dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Style.BackColor = Color.Pink;
            }
            else
            {
                // With the original MSDN code the else block to reset the 
                // cell style was not needed.
                dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Style.BackColor = dataGridView1.DefaultCellStyle.BackColor;
            }

        }
    }
}

1. My theory is that this is similar to the confusion people have over the .Refresh() method, where the DataGridView has two very distinct views of itself, one being the rectangle painted on screen and the other being the underlying data. With the .Refresh() method you only repaint the rectangle, you do not refresh the data. I think this is like that - the CellFormatting event only formats during painting and doesn't do anything to the grid styles themselves.

نصائح أخرى

A possible solution would be to add a second handler to the generic printing block of code (just before the actual printing). This handler should be attached to the CellFormatting event and only save the e.cellstyle in a temporary storage (such as a dictionary of cellstyles).

All cellstyles applied during your original cellformatting will be readable in your generic printing code without the need of adjusting specific cellformatting-events that have been tied to the datagridview. At the end of the printing you can remove the handler again.

See also Is there a way to force a DataGridView to fire its CellFormatting event for all cells?

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top