如何在特定列中突出显示 DataGridView 中的搜索文本?
How to highlight search text in DataGridView in specific column?
参考这个问题 ,解决方案有效,但它在整个数据网格视图中突出显示搜索字符串。
我的问题是,是否可以在特定列中突出显示搜索文本?
这是解决方案的代码副本:
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();
}
通常,当 owner-drawing 一个 Control
事件用于整个区域时 Paint
。
DataGridView.CellPainting事件不同; DGV 中的每个(可见)Cell
分别被调用。
这意味着对于某些 Cells
、Rows
或 Columns
,您可以完全忽略它,只需检查要绘制的单元格即可。
DataGridViewCellPaintingEventArgs包括
e.ColumnIndex
和 e.RowIndex
。您可以通过像这样测试某个列名来解决您的问题:
if (dataGridView1.Columns[e.ColumnIndex].Name != "name") return;
您还可以测试要包含或排除的列列表:
var names = new List<string> {"firstname", "lastname"};
string colName = dataGridView1.Columns[e.ColumnIndex].Name;
if (names.Contains(colName)) return;
或者像这样破解它:
string names = " firstname lastname ";
string colName = dataGridView1.Columns[e.ColumnIndex].Name;
if (names.Contains(" " + colName + " ")) return;
Rows
没有 Names
,因此您需要检查它们的索引。请注意,行 headers 列以及列 headers 行的索引为 -1
,可以像其他单元格一样进行绘制和跳过。
可以在 DataGridViewCellPaintingEventArgs , PaintParts, RowPrePaint , RowPostPaint ..
上的 MSDN 上找到有关绘制 DGV 的其他值得注意的详细信息
参考这个问题
我的问题是,是否可以在特定列中突出显示搜索文本?
这是解决方案的代码副本:
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();
}
通常,当 owner-drawing 一个 Control
事件用于整个区域时 Paint
。
DataGridView.CellPainting事件不同; DGV 中的每个(可见)Cell
分别被调用。
这意味着对于某些 Cells
、Rows
或 Columns
,您可以完全忽略它,只需检查要绘制的单元格即可。
DataGridViewCellPaintingEventArgs包括
e.ColumnIndex
和 e.RowIndex
。您可以通过像这样测试某个列名来解决您的问题:
if (dataGridView1.Columns[e.ColumnIndex].Name != "name") return;
您还可以测试要包含或排除的列列表:
var names = new List<string> {"firstname", "lastname"};
string colName = dataGridView1.Columns[e.ColumnIndex].Name;
if (names.Contains(colName)) return;
或者像这样破解它:
string names = " firstname lastname ";
string colName = dataGridView1.Columns[e.ColumnIndex].Name;
if (names.Contains(" " + colName + " ")) return;
Rows
没有 Names
,因此您需要检查它们的索引。请注意,行 headers 列以及列 headers 行的索引为 -1
,可以像其他单元格一样进行绘制和跳过。
可以在 DataGridViewCellPaintingEventArgs , PaintParts, RowPrePaint , RowPostPaint ..
上的 MSDN 上找到有关绘制 DGV 的其他值得注意的详细信息