Reputation: 2448
Reference to this question Highlight search in datagridview, solution works, but it higlight search string in whole datagridview.
My Question is, is it possible to higlight search text in specific column?
Here is copy of code from solution:
string keyValue = "Co"; //search text
private void dataGridView1_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
{
if (e.Value == null) return;
StringFormat sf = StringFormat.GenericTypographic;
sf.FormatFlags = sf.FormatFlags | StringFormatFlags.MeasureTrailingSpaces | StringFormatFlags.DisplayFormatControl;
e.PaintBackground(e.CellBounds, true);
SolidBrush br = new SolidBrush(Color.White);
if (((int)e.State & (int)DataGridViewElementStates.Selected) == 0)
br.Color = Color.Black;
string text = e.Value.ToString();
SizeF textSize = e.Graphics.MeasureString(text, Font, e.CellBounds.Width, sf);
int keyPos = text.IndexOf(keyValue, StringComparison.OrdinalIgnoreCase);
if (keyPos >= 0)
{
SizeF textMetricSize = new SizeF(0, 0);
if (keyPos >= 1)
{
string textMetric = text.Substring(0, keyPos);
textMetricSize = e.Graphics.MeasureString(textMetric, Font, e.CellBounds.Width, sf);
}
SizeF keySize = e.Graphics.MeasureString(text.Substring(keyPos, keyValue.Length), Font, e.CellBounds.Width, sf);
float left = e.CellBounds.Left + (keyPos <= 0 ? 0 : textMetricSize.Width) + 2;
RectangleF keyRect = new RectangleF(left, e.CellBounds.Top + 1, keySize.Width, e.CellBounds.Height - 2);
var fillBrush = new SolidBrush(Color.Yellow);
e.Graphics.FillRectangle(fillBrush, keyRect);
fillBrush.Dispose();
}
e.Graphics.DrawString(text, Font, br, new PointF(e.CellBounds.Left + 2, e.CellBounds.Top + (e.CellBounds.Height - textSize.Height) / 2), sf);
e.Handled = true;
br.Dispose();
}
Upvotes: 1
Views: 587
Reputation: 54433
Usually, when owner-drawing a Control
the Paint
event is used for the whole area.
The DataGridView.CellPainting event is different; it is called for every (visible) Cell
in the DGV separately.
This means that you can completely dimiss it for some Cells
, Rows
or Columns
simply by checking which Cell it is about to paint.
The DataGridViewCellPaintingEventArgs include
e.ColumnIndex
and e.RowIndex
. You can solve your problem by testing for a certain column name like this:
if (dataGridView1.Columns[e.ColumnIndex].Name != "name") return;
You could also test for a list of columns to include or exclude:
var names = new List<string> {"firstname", "lastname"};
string colName = dataGridView1.Columns[e.ColumnIndex].Name;
if (names.Contains(colName)) return;
Or hack it like this:
string names = " firstname lastname ";
string colName = dataGridView1.Columns[e.ColumnIndex].Name;
if (names.Contains(" " + colName + " ")) return;
Rows
don't have Names
, so you need to check for their indices. Note that the rows headers column as well as the column headers row have -1
as their index and can be both painted and skipped like other cells.
Other noteworthy details on paint a DGV can be found on MSDN on DataGridViewCellPaintingEventArgs , PaintParts, RowPrePaint , RowPostPaint ..
Upvotes: 1