2010-01-12 23 views
8

我有一個應用程序連接到遠程服務器並在需要時輪詢數據。它有一個TreeView,其中節點表示可用的對象,文本的顏色表示數據是否已加載;灰色斜體表示未加載,加載黑色常規文本。TreeView.DrawNode問題 - OwnerDrawText

目前我已經設置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. 當選擇了一個節點,集中與否,它不包圍所有文字,example(我希望imgur是確定)。
  2. 節點聚焦時,虛線輪廓也不顯示。如果您將其與example進行比較。在文本中的「日誌」節點正在使用e.DefaultDraw = true

我試着按照this問題給出的例子。它看起來像這樣:

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

但是,結果是this。 (注意,用粉紅色來區分顏色)。如您所見,突出顯示的背景不會一直延伸到焦點虛線所在的位置。還有另一個盒子也被繪製。

我對如何解決這個問題稍有不解。我所需要的是在裝入東西時使用灰色斜體文本。第一種也是最簡單的方法不太合適,第二種方法覺得我太過分了。

畢竟,有沒有人有任何建議如何正確地做到這一點,因爲有一個更簡單的方法。

預先感謝您。

+0

非常感謝'if(!e.Node.IsVisible)return;'沒有它,我有很多問題! – Daywalker 2018-01-29 06:01:40

回答

14

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

+1

當然,這將是那麼簡單!這完全奏效,非常感謝。現在,我可以在哪裏使用DrawText找到關於TreeView的信息? – 2010-01-13 14:10:59

+2

這仍然沒有糾正所有的圖形故障。即使我的DrawNode處理程序只是將DrawDefault設置爲true並立即返回,仍會導致選擇矩形背景的殘餘部分在未選中節點後保留。此外,使用DrawMode = OwnerDrawText時,文本偏離中心(垂直),即使DrawDefault是所有使用的。它需要向下移動一個像素以匹配DrawMode = Normal時呈現的內容。問題在於控件的繪圖方法是Windows本地繪圖代碼和框架繪圖代碼的混合,而且它們非常不一致。 – Triynko 2011-10-14 18:00:31