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で強調表示される文字列を示しています。

|* / *| が前後にある ANGLE BRACKET で囲まれた文字列の一部 強調表示されているはずですが、最後のエントリのみが強調表示されています。 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);

Xと を初期化することさえしませんWidth(したがって、デフォルトでは空になります)。では、どのようにレンダリングできますか???

質問をするすべての人にこれを話したいと思います。実際のコードを投稿してください。単純化した後にそれがどれほど間違っているかがわからない場合は、単純化しようとしないでください。上記のコードを除いて、問題を引き起こす可能性のあるものは見つかりません (もちろん、テストされていません。簡単なスキャンです)。私はあなたのために別のコードを書いてみましたが、これもテスト済みです。問題は、テキスト境界を正確に決定できるように、文字列を描画して文字列を一緒に測定する必要があることです。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 に答える