模仿wind系統界面,重繪Treeview + - 號圖標
一,首先需要圖片 ,用於替換原有的 +-號

二、新建Tree擴展類 TreeViewEx繼承TreeView
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
/*******************************************************************
* Copyright (C) 版權所有
* 文件名稱:TreeViewEx
* 命名空間:TestRecentMenu
* 創建時間:2018/12/18 16:49:08
* 作 者: wangyonglai
* 描 述:
* 修改記錄:
* 修改人:
* 版 本 號:v1.0.0
**********************************************************************/
namespace TestRecentMenu
{
public class TreeViewEx : TreeView
{
private bool ArrowKeyUp = false;
private bool ArrowKeyDown = false;
private System.Windows.Forms.ImageList arrowImageList1;
/*1節點被選中 ,TreeView有焦點*/
private SolidBrush brush1 = new SolidBrush(Color.FromArgb(209, 232, 255));//填充顏色
private Pen pen1 = new Pen(Color.FromArgb(102, 167, 232), 1);//邊框顏色
/*2節點被選中 ,TreeView沒有焦點*/
private SolidBrush brush2 = new SolidBrush(Color.FromArgb(247, 247, 247));
private Pen pen2 = new Pen(Color.FromArgb(222, 222, 222), 1);
/*3 MouseMove的時候 畫光標所在的節點的背景*/
private SolidBrush brush3 = new SolidBrush(Color.FromArgb(229, 243, 251));
private Pen pen3 = new Pen(Color.FromArgb(112, 192, 231), 1);
public const int WM_PRINTCLIENT = 0x0318;
public const int PRF_CLIENT = 0x00000004;
//替換+-號圖標的imagelist
public ImageList arrowImageList
{
get
{
return arrowImageList1;
}
set
{
arrowImageList1 = value;
}
}
public TreeViewEx()
{
//雙緩存防止屏幕抖動
//this.SetStyle(ControlStyles.UserPaint, true);
this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint | ControlStyles.DoubleBuffer, true);
this.UpdateStyles();
this.DrawMode = TreeViewDrawMode.OwnerDrawAll;
this.FullRowSelect = true;
this.HotTracking = true;
this.HideSelection = false;
this.ShowLines = false;
this.ShowNodeToolTips = true;
this.ItemHeight = 20;
}
protected override void OnDrawNode(DrawTreeNodeEventArgs e)
{
base.OnDrawNode(e);
#region 1 選中的節點背景=========================================
Rectangle nodeRect = new Rectangle(1, e.Bounds.Top, e.Bounds.Width - 3, e.Bounds.Height - 1);
if (e.Node.IsSelected)
{
if (this.Focused)
{
e.Graphics.FillRectangle(brush1, nodeRect);
e.Graphics.DrawRectangle(pen1, nodeRect);
}
else
{
e.Graphics.FillRectangle(brush2, nodeRect);
e.Graphics.DrawRectangle(pen2, nodeRect);
}
}
else if ((e.State & TreeNodeStates.Hot) != 0 && e.Node.Text != "")//|| currentMouseMoveNode == e.Node)
{
e.Graphics.FillRectangle(brush3, nodeRect);
e.Graphics.DrawRectangle(pen3, nodeRect);
}
else
{
e.Graphics.FillRectangle(Brushes.White, e.Bounds);
}
#endregion
#region 2 +-號繪制=========================================
Rectangle plusRect = new Rectangle(e.Node.Bounds.Left - 32, nodeRect.Top + 6, 9, 9); // +-號的大小 是9 * 9
if (e.Node.IsExpanded)
e.Graphics.DrawImage(arrowImageList.Images[1], plusRect);
else if (e.Node.IsExpanded == false && e.Node.Nodes.Count > 0)
e.Graphics.DrawImage(arrowImageList.Images[0], plusRect);
/*測試用 畫出+-號出現的矩形*/
//if (e.Node.Nodes.Count > 0)
// e.Graphics.DrawRectangle(new Pen(Color.Red), plusRect);
#endregion
#region 3 畫節點文本=========================================
Rectangle nodeTextRect = new Rectangle(
e.Node.Bounds.Left,
e.Node.Bounds.Top + 4,
e.Node.Bounds.Width + 2,
e.Node.Bounds.Height
);
nodeTextRect.Width += 4;
nodeTextRect.Height -= 4;
e.Graphics.DrawString(e.Node.Text,
e.Node.TreeView.Font,
new SolidBrush(Color.Black),
nodeTextRect);
//畫子節點個數 (111)
if (e.Node.GetNodeCount(true) > 0)
{
e.Graphics.DrawString(string.Format("({0})", e.Node.GetNodeCount(true)),
new Font("Arial", 8),
Brushes.Gray,
nodeTextRect.Right - 4,
nodeTextRect.Top -2);
}
///*測試用,畫文字出現的矩形*/
//if (e.Node.Text != "")
// e.Graphics.DrawRectangle(new Pen(Color.Blue), nodeTextRect);
#endregion
#region 4 畫IImageList 中的圖標===================================================================
int currt_X = e.Node.Bounds.X;
if (this.ImageList != null && this.ImageList.Images.Count > 0)
{
//圖標大小16*16
Rectangle imagebox = new Rectangle(
e.Node.Bounds.X - 3 - 16,
e.Node.Bounds.Y + 2,
16,//IMAGELIST IMAGE WIDTH
16);//HEIGHT
int index = e.Node.ImageIndex;
string imagekey = e.Node.ImageKey;
if (imagekey != "" && this.ImageList.Images.ContainsKey(imagekey))
e.Graphics.DrawImage(this.ImageList.Images[imagekey], imagebox);
else
{
if (e.Node.ImageIndex < 0)
index = 0;
else if (index > this.ImageList.Images.Count - 1)
index = 0;
e.Graphics.DrawImage(this.ImageList.Images[index], imagebox);
}
currt_X -= 19;
/*測試 畫IMAGELIST的矩形*/
//if (e.Node.ImageIndex > 0)
// e.Graphics.DrawRectangle(new Pen(Color.Black, 1), imagebox);
}
#endregion
}
protected override void OnBeforeSelect(TreeViewCancelEventArgs e)
{
base.OnBeforeSelect(e);
if (e.Node != null)
{
//禁止選中空白項
if (e.Node.Text == "")
{
//響應上下鍵
if (ArrowKeyUp)
{
if (e.Node.PrevNode != null && e.Node.PrevNode.Text != "")
this.SelectedNode = e.Node.PrevNode;
}
if (ArrowKeyDown)
{
if (e.Node.NextNode != null && e.Node.NextNode.Text != "")
this.SelectedNode = e.Node.NextNode;
}
e.Cancel = true;
}
}
}
/// <summary>
/// 防止在選擇設,treeNode閃屏
/// </summary>
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
if (!DesignMode)
{
cp.ExStyle |= 0x02000000;// Turn on WS_EX_COMPOSITED
}
return cp;
}
}
}
}
生成后拖動控件到界面中,實際效果如下

