1

我试图在我的 dataGrid 视图中突出显示字符串列表。为此,我使用了在 dataGridView 中突出显示关键字的现有代码。但结果代码仅突出显示列表的最后一次出现(即最后一次获取的记录)。这是我尝试过的

            private void dvg_ClauseSent_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
    {
        foreach (string sw in HighlightStrings) // HighlightStringsis the list of string containing all strings I need to highlight in DataGrid view
        {
            int strt = 0;
            int cnt = -1;
            int idx = -1;
            TextFormatFlags flags = TextFormatFlags.Default | TextFormatFlags.NoPrefix;
            if ((((e.RowIndex >= 0) && (e.ColumnIndex >= 0))))
            {
                e.Handled = true;
                e.PaintBackground(e.CellBounds, true);
                if (!string.IsNullOrEmpty(sw))
                {
                    string val = e.FormattedValue.ToString();
                    int sindx = val.IndexOf(sw);
                    if ((sindx >= 0))
                    {
                        while (strt != -1)
                        {
                            strt = val.IndexOf(sw, idx + 1);
                            cnt += 1;
                            idx = strt;
                            if (strt != -1)
                            {
                                if (strt != 0 && ((strt + sw.Length) != val.Length))
                                {
                                    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
                                    // and the size of the search word
                                  // paint the background behind the search word
                                    e.Graphics.FillRectangle(hl_brush, hl_rect);
                                    hl_brush.Dispose();
                                }
                            }
                        }
                    }
                }
            }
            // paint the content as usual
            e.PaintContent(e.CellBounds);
        }
    }

附加截图

以下屏幕截图显示了应在 dataGridView http://i42.tinypic.com/2dtrea1.png中显示为高亮的字符串

括在角括号中的部分字符串,后接/前接 |* / *| 应该突出显示,但只有最后一个条目被突出显示。 http://i39.tinypic.com/30cbw9l.png

任何帮助将不胜感激...

4

1 回答 1

2

你的代码有这个奇怪的东西:

Rectangle hl_rect = new Rectangle();
hl_rect.Y = (e.CellBounds.Y + 2);
hl_rect.Height = (e.CellBounds.Height - 5);

您甚至没有初始化Xand Width(因此它们默认为空)。那怎么渲染???

我想和所有会问问题的人谈谈这个,请发布您的实际代码。如果你不明白简化后的错误程度,请不要尝试简化它。除了上面的代码,我没有发现任何可能导致问题的东西(它当然没有经过测试,只是快速扫描)。我已经尝试为您编写另一个代码,也经过测试。问题是我们必须绘制字符串并一起测量字符串,以便可以准确地确定Text Bound 。TextRenderingHint.AntiAlias也应该使用,尽管有时没有它也可以工作。绘制的文本可能看起来有点模糊,但可以通过使用大字体部分消除,越大越好。这是给你的代码。

private void dataGridView1_CellPainting(object sender, 
                                        DataGridViewCellPaintingEventArgs e) {
     if (e.RowIndex > -1 && e.ColumnIndex > -1 && e.Value != null) {
         string value = e.Value.ToString();
         foreach (var s in HighlightStrings) {
            int i = 0;
            while (i < value.Length && (i = value.IndexOf(s,i))!=-1) {
              if (!e.Handled){
                  e.Handled = true;
                  e.PaintBackground(e.ClipBounds, true);
               }                        
               StringFormat sf = StringFormat.GenericTypographic;
               sf.LineAlignment = StringAlignment.Center; 
               RectangleF textBounds = GetTextBounds(e.Graphics, 
                                                     value, i, s.Length,
                                                     e.CellBounds, 
                                                     e.CellStyle.Font, sf);
              //highlight it
              e.Graphics.FillRectangle(Brushes.Yellow, textBounds);
              i += s.Length;
              using (Brush brush = new SolidBrush(e.CellStyle.ForeColor)) {
                 //draw string , don't use PaintContent
                 e.Graphics.DrawString(value, e.CellStyle.Font, brush,
                                       e.CellBounds, sf);
              }
            }
         }                
     }
 }
 public RectangleF GetTextBounds(Graphics g, string text, 
                                 int subIndex, int subLength, 
                                 RectangleF layout, 
                                 Font font, StringFormat sf) {
      var charRange = new CharacterRange(0, text.Length);
      var subCharRange = new CharacterRange(subIndex, subLength);
      sf.SetMeasurableCharacterRanges(new[]{ charRange, subCharRange });
      var regions = g.MeasureCharacterRanges(text, font, layout, sf);
      return regions.Length < 2 ? RectangleF.Empty : regions[1].GetBounds(g);
 }

注意:我们必须使用的原因DrawString是正如我所说的要TextBound精确测量。如果您有某种方法可以精确测量它而无需自己绘制字符串,您可以使用PaintContent.

在此处输入图像描述

于 2013-11-10T08:06:54.283 回答