2017-03-22 127 views
1

有沒有辦法自定義一個winform treeview來獲取類似的東西?自定義樹形視圖

enter image description here

的目的是爲具有由父項一種顏色一個定義一個三角形,而不是+/-圖標來開發項目。

+1

'treeView1.DrawMode = TreeViewDrawMode.OwnerDrawAll;' – LarsTech

回答

1

使用TreeViewDrawMode.OwnerDrawText所以縮進將由TreeView進行調整。除此之外,你應該實施完整的繪畫。

public sealed class AdvancedTreeView : TreeView 
{ 
    public AdvancedTreeView() 
    { 
     DrawMode = TreeViewDrawMode.OwnerDrawText; 
     ShowLines = false; 
     AlternateBackColor = BackColor; 
    } 

    public Color AlternateBackColor { get; set; } 

    protected override void OnDrawNode(DrawTreeNodeEventArgs e) 
    { 
     // background 
     Color backColor = (GetTopNodeIndex(e.Node) & 1) == 0 ? BackColor : AlternateBackColor; 
     using (Brush b = new SolidBrush(backColor)) 
     { 
      e.Graphics.FillRectangle(b, new Rectangle(0, e.Bounds.Top, ClientSize.Width, e.Bounds.Height)); 
     } 

     // icon 
     if (e.Node.Nodes.Count > 0) 
     { 
      Image icon = GetIcon(e.Node.IsExpanded); // TODO: true=down;false:right 
      e.Graphics.DrawImage(icon, e.Bounds.Left - icon.Width - 3, e.Bounds.Top); 
     } 

     // text (due to OwnerDrawText mode, indenting of e.Bounds will be correct) 
     TextRenderer.DrawText(e.Graphics, e.Node.Text, Font, e.Bounds, ForeColor); 

     // indicate selection (if not by backColor): 
     if ((e.State & TreeNodeStates.Selected) != 0) 
      ControlPaint.DrawFocusRectangle(e.Graphics, e.Bounds); 
    } 

    private int GetTopNodeIndex(TreeNode node) 
    { 
     while (node.Parent != null) 
      node = node.Parent; 

     return Nodes.IndexOf(node); 
    } 
} 

爲了得到與截圖類似的結果,只需設置顏色即可。

advancedTreeView1.BackColor = Color.DeepSkyBlue; 
advancedTreeView1.AlternateBackColor = Color.LightBlue; 
+0

我試過你的解決方案,但我可能錯過了一些東西。我創建了一個'AdvancedTreeView',我用child添加了10個節點(之前用一個標準的'TreeView'測試過),但它只顯示一個背景DeepSkyBlue着色。我在'OnDrawNode'中添加了一個斷點,這個函數永遠不會被調用。 –

+0

如果'DrawMode'只是'Normal',則調用它。 – taffer

+0

我修改了我的樹,現在它正在工作(可能沒有添加節點)。謝謝 –

1

只需在TreeView的屬性中將DrawMode設置爲「OwnerDrawAll」即可。請記住,你必須自己繪製它,並且必須處理TreeView_DrawNode事件。下面是事件處理的例子:

private void TreeListView_DrawNode(object sender, DrawTreeNodeEventArgs e) 
    { 
     if (e.Bounds.Height == 0) 
      return; 

     e.Graphics.FillRectangle(new SolidBrush((e.Node.Parent?.Index ?? e.Node.Index) % 2 == 0 ? Color.Blue : Color.Aqua), e.Bounds); 

     if (e.Node.Nodes.Count > 0) 
     { 
      if (!e.Node.IsExpanded) 
       e.Graphics.FillPolygon(Brushes.Red, 
        new[] 
        { 
         new PointF(e.Bounds.X + e.Bounds.Height/10, e.Bounds.Y + e.Bounds.Height/10), 
         new PointF(e.Bounds.X + e.Bounds.Height/10, e.Bounds.Y + e.Bounds.Height * 0.9f), 
         new PointF(e.Bounds.X + e.Bounds.Height, e.Bounds.Y + e.Bounds.Height/2) 
        }); 
      else 
       e.Graphics.FillPolygon(Brushes.Red, 
        new[] 
        { 
         new PointF(e.Bounds.X + e.Bounds.Height/10, e.Bounds.Y + e.Bounds.Height/10), 
         new PointF(e.Bounds.X + e.Bounds.Height, e.Bounds.Y + e.Bounds.Height/10), 
         new PointF(e.Bounds.X + e.Bounds.Height/2, e.Bounds.Y + e.Bounds.Height) 
        }); 
     } 
     e.Graphics.DrawString(e.Node.Text, new Font(FontFamily.GenericMonospace, e.Bounds.Height * 0.7f), 
      new SolidBrush(Color.Black), 
      new Rectangle(e.Bounds.X + e.Bounds.Height, e.Bounds.Y, e.Bounds.Width, e.Bounds.Height)); 
    } 
+0

是否有'TextRenderer.DrawText'和'e.Graphics.DrawString'之間的差? –

+0

有 - 看看這個:http://stackoverflow.com/questions/8283631/graphics-drawstring-vs-textrenderer-drawtextwhich-can-deliver-better-quality – MetaColon