Mannas S
Mannas S

Reputation: 75

Why does adding colored rectangles to datagridview cell using CellPainting-method make text in cell look blurry?

Wanting to highlight words in a datagridview cell with a colored background, i found some code (probably here on SO) that uses the "CellPainting"-method of the datagridview. It finds the word in the text and puts a colored background behind it. This works fine, but recently i changed the code so it would be able to highlight more than one word (each with a different color). This also works, but i noticed that when i have more words that are highlighted, the text becomes blurry (see picture).

I can't seem to find why. Is this a performance issue? Or is the text printed double... I don't seem to find why.

Blurry lines

Below i included the code in the CellPainting-method.

EDIT: Thanks to Stefan's answer a saw my nooby mistake! The "e.PaintContent(e.CellBounds);" should be outside the for loop. This was my intention, but misplaced it. Code below is changed, now it works without blurrieness. I left line that was positioned wrong as comment in the code below.

private void dataGridView1_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
{
    // High light and searching apply over selective fields of grid.  
    if (e.RowIndex > -1 && e.ColumnIndex > -1)
    {
        // Check data for search  
        if (HighlightText?.Count > 0 && HighlightColor?.Count > 0 && HighlightColor.Count >= HighlightText.Count)
        {

            String gridCellValue = e.FormattedValue.ToString();
            int startIndexInCellValue;
            // check the index of search text into grid cell.  

            bool BackgroundPainted = false;
            for (int i = 0; i < HighlightText.Count; i++)
            {
                if ((startIndexInCellValue = gridCellValue.ToLower().IndexOf(HighlightText[i])) >= 0)
                {
                    if (BackgroundPainted == false)
                    {
                        e.Handled = true;
                        e.PaintBackground(e.CellBounds, true);
                        BackgroundPainted = true;
                    }
                    //the highlite rectangle  
                    Rectangle hl_rect = new Rectangle();
                    hl_rect.Y = e.CellBounds.Y + 2;
                    hl_rect.Height = e.CellBounds.Height - 5;
                    //find the size of the text before the search word in grid cell data.  
                    String sBeforeSearchword = gridCellValue.Substring(0, startIndexInCellValue);
                    //size of the search word in the grid cell data  
                    String sSearchWord = gridCellValue.Substring(startIndexInCellValue, HighlightText[i].Length);
                    Size s1 = TextRenderer.MeasureText(e.Graphics, sBeforeSearchword, e.CellStyle.Font, e.CellBounds.Size);
                    Size s2 = TextRenderer.MeasureText(e.Graphics, sSearchWord, e.CellStyle.Font, e.CellBounds.Size);
                    if (s1.Width > 5)
                    {
                        hl_rect.X = e.CellBounds.X + s1.Width - 5;
                        hl_rect.Width = s2.Width - 6;
                    }
                    else
                    {
                        hl_rect.X = e.CellBounds.X + 2;
                        hl_rect.Width = s2.Width - 6;
                    }
                    SolidBrush hl_brush = new SolidBrush(HighlightColor[i]);
                    //paint the background behind the search word  
                    e.Graphics.FillRectangle(hl_brush, hl_rect);
                    hl_brush.Dispose();
                }
                //This was the wrong position
                //if (BackgroundPainted) { e.PaintContent(e.CellBounds); } 
            }
            //This is the right position
            if (BackgroundPainted) { e.PaintContent(e.CellBounds); }
        }
    }
}

Upvotes: 2

Views: 132

Answers (1)

Stefan
Stefan

Reputation: 652

Yes, I think the cell content is painted multiple times by calling

e.PaintContent(e.CellBounds)

every iteration of your loop. This will most likely paint the text as well as the highlights. So when two parts are highlighted, the text is painted twice as well.

The solution would be to paint the text seperately once.

Upvotes: 1

Related Questions