Is there a way to customize a winform treeview to get something like ?
The purpose is to have one color by parent item an define a triangle instead of +/- icons to develop item.
Is there a way to customize a winform treeview to get something like ?
The purpose is to have one color by parent item an define a triangle instead of +/- icons to develop item.
Use TreeViewDrawMode.OwnerDrawText
so the indenting will be adjusted by the TreeView
. Apart from that, you should implement the full painting.
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);
}
}
To get the result similar to your screenshot just set the colors and you are done.
advancedTreeView1.BackColor = Color.DeepSkyBlue;
advancedTreeView1.AlternateBackColor = Color.LightBlue;
Simply set the DrawMode to "OwnerDrawAll" in the properties of the TreeView. Keep in mind though, that you have to paint it all yourself then and have to handle the TreeView_DrawNode event. Here's an example for the event handling:
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));
}