Introduction


This blog is extension of my previous blog: Searching in FlexGrid, in which we discussed the  searching of particular text in cells of C1FlexGrid. If found, the cells containing the search string were redrawn with a different color.

In this particular blog, we will focus on drawing the search string with a different color, rather than the complete cell.

Background


Like said in the previous blog, its all about human desire that never ends.

The requirement here is to draw only the search string with different color, rather than the complete cell. Also if the cell content has more than one instance of the search string, each part of that content should be drawn with different color.

This is similar to function performed by Google Chrome wherein, typing characters in search box simultaneously highlights each instance of search string on that page. This blog is all about implementing the same functionality in C1FlexGrid.

Implementation


The approach adopted is to find the search string by going character by character through the complete text of the loaded document and then applying formatting by changing the Forecolor.
Grid_Search Demo

The OwnerDrawCell event of C1FlexGrid allows you to override every visual aspect of the cell. Here, this event is used to redraw the characters of cells containing the search string. To begin with, set ‘DrawMode’ property of C1FlexGrid to ‘OwnerDraw’ so that the grid triggers OwnerDrawCell event whenever a cell needs to be painted.


//Enable control to fire OwnerDrawCell Event
c1FlexGrid1.DrawMode = C1.Win.C1FlexGrid.DrawModeEnum.OwnerDraw;


In changing content in the search box, the OwnerDrawCell event is forced to fire in order to iterate through each cell's content and check the presence of the search string. Once found, each instance of the string will be rendered with different ForeColor(Red, in this case). In order to call the OwnerDrawCell event manually, we are selecting all the cells of C1FlexGrid as follows.


C1.Win.C1FlexGrid.CellRange rg = new C1.Win.C1FlexGrid.CellRange();
rg.c1 = 1;
rg.c2 = c1FlexGrid1.Cols.Count - 1;
rg.r1 = 1;
rg.r2 = c1FlexGrid1.Rows.Count - 1;
//Select all cells to search the Grid and redraw search results with Red ForeColor
c1FlexGrid1.Select(rg);


A flag ‘_StartSearch’ is used to differentiate between default rendering and the manual rendering (for searching) in the cell.


void c1FlexGrid1_OwnerDrawCell(object sender, C1.Win.C1FlexGrid.OwnerDrawCellEventArgs e)
{
//Test whether OwnerDrawCell is used for searching or default drawing of cells
if (_StartSearch)
{
stringCellContent = e.Text;
if (CellContent.Contains(tbSearchBox.Text))
{
//To check no of times the search string appears in the current cell
_OccuranceOfSearchedText = Regex.Matches(CellContent, tbSearchBox.Text).Count;
if (_OccuranceOfSearchedText == 1)
{
for (inti = 0; i<CellContent.Length; )
{
if (CellContent[i] == tbSearchBox.Text[0])
{
found = true;
//To check whether the search string is found in cell or not
for (int j = 1, k = i+1; j <tbSearchBox.Text.Length; j++, k++)
{
if (k == CellContent.Length)
{
found = false;
}
else if (CellContent[k] != tbSearchBox.Text[j])
{
found = false;
}
}
if (found)
{
for (int l = i; l < (i + tbSearchBox.Text.Length); l++)
{
//Color the Search Result with Red
e.Graphics.DrawString(CellContent[l].ToString(), c1FlexGrid1.Font, brushRed, e.Bounds.X + x, e.Bounds.Y);
//Next character needs to be shifted right;
//depending on the space occupied by the previous character as per its FontSize/FontStyle
x += (e.Graphics.MeasureString(CellContent[l].ToString(), this.c1FlexGrid1.Font)).Width - 3;
}
for (int l = i + tbSearchBox.Text.Length; l <CellContent.Length; l++)
{
e.Graphics.DrawString(CellContent[l].ToString(), c1FlexGrid1.Font, brushBlack, e.Bounds.X + x, e.Bounds.Y);
x += (e.Graphics.MeasureString(CellContent[l].ToString(), this.c1FlexGrid1.Font)).Width - 3;
}
break;
}
else
{
e.Graphics.DrawString(CellContent[i].ToString(), c1FlexGrid1.Font, brushBlack, e.Bounds.X + x, e.Bounds.Y);
x += (e.Graphics.MeasureString(CellContent[i].ToString(), this.c1FlexGrid1.Font)).Width - 3;
++i;
}
}
else
{
e.Graphics.DrawString(CellContent[i].ToString(), c1FlexGrid1.Font, brushBlack, e.Bounds.X + x, e.Bounds.Y);
x += (e.Graphics.MeasureString(CellContent[i].ToString(), this.c1FlexGrid1.Font)).Width - 3;
++i;
}
}
}
else
{
//Similar implementation when multiple instances of search string are there in the cell content
}
e.Handled = true;
}
}

//Whether Search completed throughout the cells of grid
if (e.Row == c1FlexGrid1.Rows.Count &&e.Col == c1FlexGrid1.Cols.Count)
{
_StartSearch = false;
}
}
}

Working Sample


C# Sample