如何在DataGridView中突出显示搜索阿拉伯文本? [英] How to highlight search Arabic text in DataGridView?

查看:53
本文介绍了如何在DataGridView中突出显示搜索阿拉伯文本?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在DataGridView中突出显示给定的搜索文本,但数据使用阿拉伯语。我已经尝试了CellPainting事件来查找搜索文本的边界并绘制FillRectangle,但是我无法完全获得搜索文本的边界。





以下代码是我使用的代码:

  private void dgv_CellPainting(object sender,DataGridViewCellPaintingEventArgs e)
{
//高亮显示并在网格的选定字段上应用搜索。
if(e.RowIndex< -1&& e.ColumnIndex> -1&& dgv.Columns [e.ColumnIndex] .Name!= Id)
{
//检查搜索数据
if(!String.IsNullOrWhiteSpace(txtSearch.Text.Trim()))
{
String gridCellValue = e.Value.ToString();
//检查搜索文本在网格单元格中的索引。
int startIndexInCellValue = gridCellValue.IndexOf(txtSearch.Text.Trim());
//如果搜索文本存在于网格单元中,则startIndexInCellValue的值将大于0或等于0
如果(startIndexInCellValue> = 0)
{
e.Handled = true;
e.PaintBackground(e.CellBounds,true);
// highlite矩形
Rectangle hl_rect = new Rectangle();
hl_rect.Y = e.CellBounds.Y + 2;
hl_rect.Height = e.CellBounds.Height-5;
//在网格单元格数据中查找搜索词之前的文本大小。
字符串sBeforeSearchword = gridCellValue.Substring(0,startIndexInCellValue);
//网格单元格数据中搜索词的大小
字符串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;
}
//用于在网格单元格
中显示突出显示的文本的颜色SolidBrush hl_brush;
hl_brush =新的SolidBrush(Color.Yellow);
//在搜索词
后面绘制背景e.Graphics.FillRectangle(hl_brush,hl_rect);
hl_brush.Dispose();
e.PaintContent(e.CellBounds);
}
}
}
}


解决方案


问题







您需要考虑每个单元格的几个因素:






  • 注意:演示中仅将DGV设置为RTL布局。


    LTR语言-LTR布局







    也许超出范围,但是对某人可能有用。



    <学前班= lang-cs prettyprint-override> private void dgv_CellPainting(对象发送者,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);如果(i <0)返回,则

    ;

    e.Handled = true;

    var g = e.Graphics;

    使用(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;


    开关(e.CellStyle.Alignment)
    {
    case DataGridViewContentAlignment.MiddleCenter:
    case DataGridViewContentAlignment.BottomCenter:
    case DataGridViewContentAlignment。 TopCenter:
    x + =(e.CellBounds.Width-valWidth)/ 2;
    x-= zs / 2;
    休息时间;
    case DataGridViewContentAlignment.MiddleRight:
    case DataGridViewContentAlignment.BottomRight:
    case DataGridViewContentAlignment.TopRight:
    x + =(e.CellBounds.Width-valWidth);
    x-= zs * 1.5f;
    休息时间;
    默认值:
    x + = zs / 2;
    休息时间;
    }

    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);
    }
    }

    私有StringFormat ToStringFormat(DataGridViewContentAlignment ca)
    {
    var sf = StringFormat.GenericTypographic;

    开关(ca)
    {
    case DataGridViewContentAlignment.MiddleCenter:
    sf.Alignment = StringAlignment.Center;
    sf.LineAlignment = StringAlignment.Center;
    休息时间;
    case DataGridViewContentAlignment.MiddleLeft:
    sf.Alignment = StringAlignment.Near;
    sf.LineAlignment = StringAlignment.Center;
    休息时间;
    case DataGridViewContentAlignment.MiddleRight:
    sf.Alignment = StringAlignment.Far;
    sf.LineAlignment = StringAlignment.Center;
    休息时间;
    case DataGridViewContentAlignment.BottomCenter:
    sf.Alignment = StringAlignment.Center;
    sf.LineAlignment = StringAlignment.Far;
    休息时间;
    case DataGridViewContentAlignment.BottomLeft:
    sf.Alignment = StringAlignment.Near;
    sf.LineAlignment = StringAlignment.Far;
    休息时间;
    case DataGridViewContentAlignment.BottomRight:
    sf.Alignment = StringAlignment.Far;
    sf.LineAlignment = StringAlignment.Far;
    休息时间;
    case DataGridViewContentAlignment.TopLeft:
    sf.Alignment = StringAlignment.Near;
    sf.LineAlignment = StringAlignment.Near;
    休息时间;
    case DataGridViewContentAlignment.TopRight:
    sf.Alignment = StringAlignment.Far;
    sf.LineAlignment = StringAlignment.Near;
    休息时间;
    case DataGridViewContentAlignment.TopCenter:
    sf.Alignment = StringAlignment.Center;
    sf.LineAlignment = StringAlignment.Near;
    休息时间;
    }

    return sf;
    }


    I want to highlight the given search text in the DataGridView but the data is in Arabic. I have tried CellPainting event to find the bounds of the search text and draw FillRectangle, but I could not exactly get the bounds of the search text.

    The following code was the one I used:

    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);
                }
            }
        }
    }
    

    解决方案

    Problem


    You need to take into account several factors for each cell:

    • The DataGridViewContentAlignment.
    • The exact size of the selected characters.
    • The zero-width characters (white spaces).
    • The size of the content.
    • The empty space.
    • The index of the first occurrence of the search string.

    All the mentioned are necessary to calculate and adjust both the location and size of the highlight rectangle.

    Here's an example:

    RTL Languages - RTL Layout


    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;
    }
    

    Here's a demo.

    Note: Only the DGV is set to RTL layout in the demo.

    LTR Languages - LTR Layout


    Maybe out of scope, however might be useful for someone.

    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;
    }
    

    这篇关于如何在DataGridView中突出显示搜索阿拉伯文本?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆