模仿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 = 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;
-
- }
- }
- }
- }
生成后拖动控件到界面中,实际效果如下
