9

リモートサーバーに接続し、必要に応じてデータをポーリングするアプリがあります。これにはTreeViewがあり、ノードは使用可能なオブジェクトを表し、テキストの色はデータがロードされているかどうかを示します。灰色の斜体はロードされていないことを示し、黒の通常のテキストはロードされています。

現在、TreeViewをOwnderDrawTextに設定し、TreeView.DrawNode関数でテキストを次のように描画しています。

private void TreeViewDrawNode(object sender, DrawTreeNodeEventArgs e)
{
    if (!e.Node.IsVisible)
    {
        return;
    }

    bool bLoaded = false;

    if (e.Bounds.Location.X >= 0 && e.Bounds.Location.Y >= 0)
    {
       if(e.Node.Tag != null)
       {
           //...
           // code determining whether data has been loaded is done here
           // setting bLoaded true or false
           //...
       }
       else
       {
           e.DrawDefault = true;
           return;
       }

       Font useFont = null;
       Brush useBrush = null;

       if (bLoaded)
       {
           useFont = e.Node.TreeView.Font;
           useBrush = SystemBrushes.WindowText;
        }
        else
        {
            useFont = m_grayItallicFont;
            useBrush = SystemBrushes.GrayText;
        }
        e.Graphics.DrawString(e.Node.Text, useFont, useBrush, e.Bounds.Location);
    }
}

それで十分だと思いましたが、これがいくつかの問題を引き起こしています。

  1. フォーカスされているかどうかに関係なく、ノードが選択されている場合、のようにすべてのテキストが含まれているわけではありません(imgurが問題ないことを願っています)。
  2. ノードにフォーカスがある場合、点線の輪郭も表示されません。このと比較すると。テキストに「log」が含まれるノードは、e.DefaultDraw=trueを使用しています。

この質問の例に従ってみました。次のようになりました。

private void TreeViewDrawNode(object sender, DrawTreeNodeEventArgs e)
 {
  if (!e.Node.IsVisible)
  {
   return;
  }

  bool bLoaded = false;

  if (e.Bounds.Location.X >= 0 && e.Bounds.Location.Y >= 0)
  {
     if(e.Node.Tag != null)
     {
      //...
      // code determining whether data has been loaded is done here
      // setting bLoaded true or false
      //...
     }
     else
     {
      e.DrawDefault = true;
      return;
     }

   //Select the font and brush depending on whether the property has been loaded
   Font useFont = null;
   Brush useBrush = null;

   if (bLoaded)
   {
    useFont = e.Node.TreeView.Font;
    useBrush = SystemBrushes.WindowText;
   }
   else
   {
    //member variable defined elsewhere
    useFont = m_grayItallicFont;
    useBrush = SystemBrushes.GrayText;
   }

   //Begin drawing of the text

   //Get the rectangle that will be used to draw
   Rectangle itemRect = e.Bounds;
   //Move the rectangle over by 1 so it isn't on top of the check box
   itemRect.X += 1;

   //Figure out the text position
   Point textStartPos = new Point(itemRect.Left, itemRect.Top);
   Point textPos = new Point(textStartPos.X, textStartPos.Y);

   //generate the text rectangle
   Rectangle textRect = new Rectangle(textPos.X, textPos.Y, itemRect.Right - textPos.X, itemRect.Bottom - textPos.Y);

   int textHeight = (int)e.Graphics.MeasureString(e.Node.Text, useFont).Height;
   int textWidth = (int)e.Graphics.MeasureString(e.Node.Text, useFont).Width;

   textRect.Height = textHeight;

   //Draw the highlighted box
   if ((e.State & TreeNodeStates.Selected) != 0)
   {
    //e.Graphics.FillRectangle(SystemBrushes.Highlight, textRect);
    //use pink to see the difference
    e.Graphics.FillRectangle(Brushes.Pink, textRect);
   }
   //widen the rectangle by 3 pixels, otherwise all of the text     won't fit
   textRect.Width = textWidth + 3;

   //actually draw the text
   e.Graphics.DrawString(e.Node.Text, useFont, useBrush, e.Bounds.Location);

   //Draw the box around the focused node
   if ((e.State & TreeNodeStates.Focused) != 0)
   {
    textRect.Width = textWidth;
    Pen focusPen = new Pen(Color.Black);
    focusPen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dot;
    e.Graphics.DrawRectangle(focusPen, textRect);
   }
  }
 }

しかし、結果はこれでした。(色を区別するためにピンクを使用していることに注意してください)。ご覧のとおり、強調表示された背景は、フォーカスされた点線がある場所までは伸びていません。また、同様に描かれている別のボックスもあります。

私はこれを修正する方法に少し困惑しています。私が欲しいのは、何かがロードされたときに灰色のイタリック体のテキストを表示することです。最初の最も単純なアプローチは完全には機能せず、2番目の方法は私がやりすぎているように感じます。

結局のところ、もっと簡単な方法が必要なので、これを適切に行う方法について誰かが何か提案がありますか。

前もって感謝します。

4

1 に答える 1

15

TextRenderer.DrawText()を使用する必要があります。これがTreeViewが使用するものであり、Graphics.DrawString()とは少し異なるテキストをレンダリングします。

于 2010-01-12T23:00:03.817 に答える