9

我有一个连接到远程服务器并在需要时轮询数据的应用程序。它有一个 TreeView,其中节点表示可用的对象,文本的颜色表示数据是否已加载;gray-italicized 表示未加载,黑色,常规文本已加载。

目前我已将 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. When a node is selected, focused or not, it doesn't envelop all of the text, example (I hope imgur is ok).
  2. 当节点聚焦时,虚线轮廓也不显示。如果将其与此示例进行比较。文本中带有“日志”的节点使用的是 e.DefaultDraw = true

我尝试按照this question中给出的示例进行操作。它看起来像这样:

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

然而,结果是这样的。(注意,使用粉红色来区分颜色)。如您所见,突出显示的背景并没有一直延伸到焦点虚线所在的位置。并且还绘制了另一个框。

我对如何解决这个问题感到有些困惑。我想要的只是在加载某些内容时显示灰色斜体文本。第一种也是最简单的方法不太奏效,第二种方法感觉我做得太多了。

毕竟,是否有人对如何正确执行此操作有任何建议,因为必须有一种更简单的方法。

先感谢您。

4

1 回答 1

15

您需要使用 TextRenderer.DrawText()。这就是 TreeView 使用的,它呈现的文本与 Graphics.DrawString() 略有不同。

于 2010-01-12T23:00:03.817 回答