C# 自定义treeview

C# 自定义treeview,c#,winforms,treeview,C#,Winforms,Treeview,有没有办法自定义winform treeview以获得类似的内容 其目的是通过父项定义一种颜色,并定义一个三角形而不是+/-图标来开发项。只需在树状视图的属性中将DrawMode设置为“OwnerDrawAll”。但是请记住,您必须自己绘制它,并且必须处理TreeView_DrawNode事件。下面是事件处理的一个示例: private void TreeListView_DrawNode(object sender, DrawTreeNodeEventArgs e) {

有没有办法自定义winform 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));
    }

使用
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;

treeView1.DrawMode=TreeViewDrawMode.OwnerDrawAllA在这里的答案有问题,所以我在那里发布了一个更完整的解决方案。我尝试了你的解决方案,但我可能错过了一些东西。我创建了一个
AdvancedTreeView
,我添加了10个带有child的节点(以前用标准
TreeView
测试过),但它只显示深蓝色的背景。我在
OnDrawNode
中添加了一个断点,该函数从未被调用。如果
DrawMode
不是
Normal
,则会调用该函数。我修改了我的树,现在它正在工作(可能没有添加节点)。谢谢我修改了你的函数
GetIcon
。现在绘制三角形,我们可以定义颜色和边距。我认为它更易于重用。在
TextRenderer.DrawText
e.Graphics.DrawString
之间有什么区别吗?有-看看这个: