Question

This is the case: I want to search for a word in a whole DataGridView through looping it's Rows, and then for each match I highlight the word. The major inflexibility I face is that columns have different System.Windows.Forms.DataGridViewContentAlignments. So in paiting (highlighting) mathced word in cells I should take care of cell's ContentAlignment.

So far I have written the following code to find the matches

private int FindAllMatches()
{
    int itemsFound = 0;
    for (int r = 0; r < dgvMain.Rows.Count; r++)
    {
        DataGridViewRow row = dgvMain.Rows[r];
        for (int c = 0; c < Columns.Count; c++)
        {
            string cellValue = (dgvMain.Rows[r].Cells[c].Value ?? "").ToString();
            if (cellValue.Contains(SearchValue.ToString()))
            {
                HighlightRow(row); // highlights whole row, weak solution
                itemsFound++;
                break;
            }
        }
    }
    return itemsFound;
}

But as you see I have currently managed to highlight the rows which have at least one match. What I need is a code to highlight only the portion of cell which matches my specific word (SearchValue).

I know I should use the CellPainting Event, but I don't know how to paint the word inside a Cell considering the Cell's ContentAlignment

Was it helpful?

Solution

I have modified the my answer to this question to consider the direction and content alignment. It works for default alignment but you have to improve the code for other alignments.

void dataGridView1_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
{
    if (e.RowIndex != -1 && e.Value != null && e.Value.ToString().Length > 5 && e.ColumnIndex == 2)
    {
        if (!e.Handled)
        {
            e.Handled = true;
            e.PaintBackground(e.CellBounds, dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Selected);
        }
        if ((e.PaintParts & DataGridViewPaintParts.ContentForeground) != DataGridViewPaintParts.None)
        {
            bool rightToLeft = this.RightToLeft == RightToLeft.Yes ? true:false;
            string text = e.Value.ToString();
            string textPart1 = text.Substring(0, text.Length - 5);
            string textPart2 = text.Substring(text.Length - 5, 5);
            Size fullsize = TextRenderer.MeasureText(text, e.CellStyle.Font);
            Size size1 = TextRenderer.MeasureText(textPart1, e.CellStyle.Font);
            Size size2 = TextRenderer.MeasureText(textPart2, e.CellStyle.Font);
            Rectangle rect1 = new Rectangle(e.CellBounds.Location, e.CellBounds.Size);
            TextFormatFlags flags = GetFlagsForCellStyleAlignment(rightToLeft, e.CellStyle.Alignment);
            TextRenderer.DrawText(e.Graphics, text, e.CellStyle.Font, rect1, Color.Crimson, flags);
            using (Brush cellForeBrush = new SolidBrush(e.CellStyle.ForeColor))
            {
                TextRenderer.DrawText(e.Graphics, textPart1, e.CellStyle.Font, rect1, e.CellStyle.ForeColor, flags);
            }
        }
    }
}

TextFormatFlags GetFlagsForCellStyleAlignment(bool rigthToLeft, DataGridViewContentAlignment alignment)
{
    TextFormatFlags flags = TextFormatFlags.Default;
    switch (alignment)
    {
        case DataGridViewContentAlignment.TopLeft:
            {
                flags = TextFormatFlags.Default;
                if (rigthToLeft)
                {
                    flags |= TextFormatFlags.Right;
                }
                break;
            }
        case DataGridViewContentAlignment.MiddleLeft:
            {
                flags = TextFormatFlags.VerticalCenter;
                if (rigthToLeft)
                {
                    flags |= TextFormatFlags.Right;
                }
                break;
            }
    }
    if (rigthToLeft)
        flags |= TextFormatFlags.RightToLeft;
    return flags;
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top