c# - 如何在 DataGridView 中突出显示搜索阿拉伯语文本?
问题描述
我想在 DataGridView 中突出显示给定的搜索文本,但数据是阿拉伯语。我尝试了 CellPainting 事件来查找搜索文本的边界并绘制 FillRectangle,但我无法准确地获得搜索文本的边界。
以下代码是我使用的代码:
private void dgv_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
{
// High light and searching apply over selective fields of grid.
if (e.RowIndex > -1 && e.ColumnIndex > -1 && dgv.Columns[e.ColumnIndex].Name != "Id")
{
// Check data for search
if (!String.IsNullOrWhiteSpace(txtSearch.Text.Trim()))
{
String gridCellValue = e.Value.ToString();
// check the index of search text into grid cell.
int startIndexInCellValue = gridCellValue.IndexOf(txtSearch.Text.Trim());
// IF search text is exists inside grid cell then startIndexInCellValue value will be greater then 0 or equal to 0
if (startIndexInCellValue >= 0)
{
e.Handled = true;
e.PaintBackground(e.CellBounds, 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, txtSearch.Text.Trim().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.Right + s1.Width - e.CellBounds.X - e.CellBounds.Left;
hl_rect.Width = s2.Width - 6;
}
else
{
hl_rect.X = e.CellBounds.X + 2;
hl_rect.Width = s2.Width - 6;
}
//color for showing highlighted text in grid cell
SolidBrush hl_brush;
hl_brush = new SolidBrush(Color.Yellow);
//paint the background behind the search word
e.Graphics.FillRectangle(hl_brush, hl_rect);
hl_brush.Dispose();
e.PaintContent(e.CellBounds);
}
}
}
}
解决方案
问题
您需要考虑每个单元格的几个因素:
- DataGridViewContentAlignment。_
- 所选字符的确切大小。
- 零宽度字符(空格)。
- 内容的大小。
- 空旷的空间。
- 搜索字符串第一次出现的索引。
所有提到的都是计算和调整高亮矩形的位置和大小所必需的。
这是一个例子:
RTL 语言 - RTL 布局
private void dgv_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
{
if (txtSearch.TextLength < 1
|| e.RowIndex < 0
|| e.ColumnIndex < 1
|| e.Value == null)
return;
var zeroWidth = "|";
var v = e.Value.ToString().Replace(" ", zeroWidth);
var f = txtSearch.Text.Replace(" ", zeroWidth);
var i = v.IndexOf(f, StringComparison.InvariantCultureIgnoreCase);
if (i < 0) return;
e.Handled = true;
var g = e.Graphics;
using (var sf = ToStringFormat(e.CellStyle.Alignment))
{
var zw = g.MeasureString(zeroWidth, e.CellStyle.Font, e.CellBounds.Width, sf).Width;
var valWidth = g.MeasureString(v, e.CellStyle.Font, e.CellBounds.Width, sf).Width;
var w = g.MeasureString(f, e.CellStyle.Font, e.CellBounds.Width, sf).Width;
var x = e.CellBounds.Right - ((e.CellBounds.Width - valWidth) / 2);
x -= g.MeasureString(v.Substring(0, i), e.CellStyle.Font,
e.CellBounds.Width, sf).Width;
x -= w;
switch (e.CellStyle.Alignment)
{
case DataGridViewContentAlignment.BottomLeft:
case DataGridViewContentAlignment.MiddleLeft:
case DataGridViewContentAlignment.TopLeft:
x += ((e.CellBounds.Width - valWidth) / 2) - zw;
break;
case DataGridViewContentAlignment.MiddleRight:
case DataGridViewContentAlignment.BottomRight:
case DataGridViewContentAlignment.TopRight:
x -= ((e.CellBounds.Width - valWidth) / 2) - zw;
break;
default:
break;
}
var r = new RectangleF(
x,
e.CellBounds.Y + 3,
w,
e.CellBounds.Height - 7);
e.PaintBackground(e.CellBounds, true);
g.FillRectangle(Brushes.Yellow, r);
e.PaintContent(e.CellBounds);
}
}
private StringFormat ToStringFormat(DataGridViewContentAlignment ca)
{
var sf = StringFormat.GenericTypographic;
switch (ca)
{
case DataGridViewContentAlignment.MiddleCenter:
sf.Alignment = StringAlignment.Center;
sf.LineAlignment = StringAlignment.Center;
break;
case DataGridViewContentAlignment.MiddleLeft:
sf.Alignment = StringAlignment.Near;
sf.LineAlignment = StringAlignment.Center;
break;
case DataGridViewContentAlignment.MiddleRight:
sf.Alignment = StringAlignment.Far;
sf.LineAlignment = StringAlignment.Center;
break;
case DataGridViewContentAlignment.BottomCenter:
sf.Alignment = StringAlignment.Center;
sf.LineAlignment = StringAlignment.Far;
break;
case DataGridViewContentAlignment.BottomLeft:
sf.Alignment = StringAlignment.Near;
sf.LineAlignment = StringAlignment.Far;
break;
case DataGridViewContentAlignment.BottomRight:
sf.Alignment = StringAlignment.Far;
sf.LineAlignment = StringAlignment.Far;
break;
case DataGridViewContentAlignment.TopLeft:
sf.Alignment = StringAlignment.Near;
sf.LineAlignment = StringAlignment.Near;
break;
case DataGridViewContentAlignment.TopRight:
sf.Alignment = StringAlignment.Far;
sf.LineAlignment = StringAlignment.Near;
break;
case DataGridViewContentAlignment.TopCenter:
sf.Alignment = StringAlignment.Center;
sf.LineAlignment = StringAlignment.Near;
break;
}
sf.FormatFlags |= StringFormatFlags.DirectionRightToLeft;
return sf;
}
这是一个演示。
注意:演示中仅将 DGV 设置为 RTL 布局。
LTR 语言 - LTR 布局
也许超出范围,但可能对某人有用。
private void dgv_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
{
if (txtSearch.TextLength < 1
|| e.RowIndex < 0
|| e.ColumnIndex < 1
|| e.Value == null)
return;
var zeroWidth = "|";
var v = e.Value.ToString().Replace(" ", zeroWidth);
var f = txtSearch.Text.Replace(" ", zeroWidth);
var i = v.IndexOf(f, StringComparison.InvariantCultureIgnoreCase);
if (i < 0) return;
e.Handled = true;
var g = e.Graphics;
using (var sf = ToStringFormat(e.CellStyle.Alignment))
{
var zs = g.MeasureString(zeroWidth, e.CellStyle.Font,
e.CellBounds.Width, sf).Width;
var valWidth = g.MeasureString(v, e.CellStyle.Font,
e.CellBounds.Width, sf).Width;
var x = g.MeasureString(v.Substring(0, i), e.CellStyle.Font,
e.CellBounds.Width, sf).Width;
var w = g.MeasureString(v.Substring(i, f.Length), e.CellStyle.Font,
e.CellBounds.Width, sf).Width;
switch (e.CellStyle.Alignment)
{
case DataGridViewContentAlignment.MiddleCenter:
case DataGridViewContentAlignment.BottomCenter:
case DataGridViewContentAlignment.TopCenter:
x += (e.CellBounds.Width - valWidth) / 2;
x -= zs / 2;
break;
case DataGridViewContentAlignment.MiddleRight:
case DataGridViewContentAlignment.BottomRight:
case DataGridViewContentAlignment.TopRight:
x += (e.CellBounds.Width - valWidth);
x -= zs * 1.5f;
break;
default:
x += zs / 2;
break;
}
var r = new RectangleF(
e.CellBounds.X + x,
e.CellBounds.Y + 3,
w,
e.CellBounds.Height - 7);
e.PaintBackground(e.CellBounds, true);
g.FillRectangle(Brushes.Yellow, r);
e.PaintContent(e.CellBounds);
}
}
private StringFormat ToStringFormat(DataGridViewContentAlignment ca)
{
var sf = StringFormat.GenericTypographic;
switch (ca)
{
case DataGridViewContentAlignment.MiddleCenter:
sf.Alignment = StringAlignment.Center;
sf.LineAlignment = StringAlignment.Center;
break;
case DataGridViewContentAlignment.MiddleLeft:
sf.Alignment = StringAlignment.Near;
sf.LineAlignment = StringAlignment.Center;
break;
case DataGridViewContentAlignment.MiddleRight:
sf.Alignment = StringAlignment.Far;
sf.LineAlignment = StringAlignment.Center;
break;
case DataGridViewContentAlignment.BottomCenter:
sf.Alignment = StringAlignment.Center;
sf.LineAlignment = StringAlignment.Far;
break;
case DataGridViewContentAlignment.BottomLeft:
sf.Alignment = StringAlignment.Near;
sf.LineAlignment = StringAlignment.Far;
break;
case DataGridViewContentAlignment.BottomRight:
sf.Alignment = StringAlignment.Far;
sf.LineAlignment = StringAlignment.Far;
break;
case DataGridViewContentAlignment.TopLeft:
sf.Alignment = StringAlignment.Near;
sf.LineAlignment = StringAlignment.Near;
break;
case DataGridViewContentAlignment.TopRight:
sf.Alignment = StringAlignment.Far;
sf.LineAlignment = StringAlignment.Near;
break;
case DataGridViewContentAlignment.TopCenter:
sf.Alignment = StringAlignment.Center;
sf.LineAlignment = StringAlignment.Near;
break;
}
return sf;
}
推荐阅读
- node.js - 使用 pm2 部署多个 Angular 4 项目
- java - How to read content of all files in the folder and in the sub directories
- angularjs - Angularjs: ReferenceError: function is not defined at Channel.onDeviceReady
- x86 - U-Boot 命令行中没有输入
- javascript - 将数据解析为单独的标记数组
- python - numexpr 是否支持特殊的贝塞尔函数?
- javascript - appendChild 在新创建的 div 中
- javascript - 从反应组件中的类访问方法
- intellij-idea - SBT + Idea 2.5 := 无法解析符号
- python - 函数集成返回“只有长度为 1 的数组可以转换为 Python 标量”