WinForm的TreeView实现Win7 Areo效果

新建一个继承自TreeView的控件类,代码如下:

using System;
using System.Windows.Forms;
using System.Drawing;
using System.Runtime.InteropServices;

namespace SenseTreeView
{
    public class SenseTreeView : TreeView
    {
        #region 控件属性

        //显示字体
        private Font _NodeFont;
        public Font NodeFont
        {
            get
            {
                return _NodeFont;
            }
            set
            {
                _NodeFont = value;
            }
        }

        //选择TreeView TreeNode时的背景色
        private Brush _BackgrountBrush;
        public Brush BackgroundBrush
        {
            get
            {
                return _BackgrountBrush;
            }
            set
            {
                _BackgrountBrush = value;
            }
        }

        //选择TreeView TreeNode时背景色的边框画笔
        private Pen _BackgroundPen;
        public Pen BackgroundPen
        {
            get
            {
                return _BackgroundPen;
            }
            set
            {
                _BackgroundPen = value;
            }
        }

        //TreeView中TreeNode展开时的节点显示图标,
        private Image _NodeExpandedImage;
        public Image NodeExpandedImage
        {
            get
            {
                return _NodeExpandedImage;
            }
            set
            {
                _NodeExpandedImage = value;
            }
        }
        //TreeView中TreeNode合拢时的节点显示图标
        private Image _NodeCollapseImage;
        public Image NodeCollapseImage
        {
            get
            {
                return _NodeCollapseImage;
            }
            set
            {
                _NodeCollapseImage = value;
            }
        }
        //TreeView中TreeNode的节点显示图标的大小
        private Size _NodeImageSize;
        public Size NodeImageSize
        {
            get
            {
                return _NodeImageSize;
            }
            set
            {
                _NodeImageSize = value;
            }
        }

        //节点显示图标离左边界的位置
        private int _NodeOffset;
        public int NodeOffset
        {
            get
            {
                return _NodeOffset;
            }
            set
            {
                _NodeOffset = value;
            }
        }

        #endregion

        #region 构造函数

        public SenseTreeView()
        {
            //设置窗体Style
            //this.SetStyle(ControlStyles.UserPaint, true);               //支持用户重绘窗体
            //this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);    //在内存中先绘制界面
            //this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);   //双缓冲,防止绘制时抖动
            //this.SetStyle(ControlStyles.DoubleBuffer, true);            //双缓冲,防止绘制时抖动 
            //this.UpdateStyles();

            //不显示树形节点显示连接线
            this.ShowLines = false;

            //设置绘制TreeNode的模式
            this.DrawMode = TreeViewDrawMode.OwnerDrawAll;

            //不显示TreeNode前的“+”和“-”按钮
            this.ShowPlusMinus = false;

            //不支持CheckedBox
            this.CheckBoxes = false;

            //设置TreeNode的行高
            SendMessage(this.Handle, TVM_SETITEMHEIGHT, 20, 0);

            //设置默认BackgroundBrush
            BackgroundBrush = new SolidBrush(Color.FromArgb(90, Color.FromArgb(205, 226, 252)));

            //设置默认BackgroundPen
            BackgroundPen = new Pen(Color.FromArgb(130, 249, 252), 1);

            //设置默认NodeFont
            NodeFont = new Font("宋体", 12, FontStyle.Regular);

            //设置默认节点显示图标及Size
            NodeExpandedImage = null;
            NodeCollapseImage = null;
            NodeImageSize = new Size(18, 18);

            //设置默认节点显示图标便宜位置
            NodeOffset = 5;
        }

        #endregion

        #region 节点绘制函数

        //绘制TreeView树中TreeNode
        protected override void OnDrawNode(DrawTreeNodeEventArgs e)
        {
            TreeNode tn = e.Node as TreeNode;
            if (tn == null)
            {
                return;
            }

            //设置Image绘制Rectangle
            Point pt = new Point(tn.Bounds.X + NodeOffset, tn.Bounds.Y);
            Rectangle rt = new Rectangle(pt, NodeImageSize);

            if ((e.State & TreeNodeStates.Selected) != 0)
            {
                //绘制TreeNode选择后的背景框
                e.Graphics.FillRectangle(BackgroundBrush, 2, tn.Bounds.Y, this.Width - 7, tn.Bounds.Height - 1);

                //绘制TreeNode选择后的边框线条
                e.Graphics.DrawRectangle(BackgroundPen, 1, tn.Bounds.Y, this.Width - 6, tn.Bounds.Height - 1);                                
            }

            //绘制节点图片
            if (NodeExpandedImage != null && NodeCollapseImage != null)
            {
                if (tn.Nodes.Count != 0)
                {
                    if (tn.IsExpanded == true)
                    {
                        e.Graphics.DrawImage(NodeExpandedImage, rt);
                    }
                    else
                    {
                        e.Graphics.DrawImage(NodeCollapseImage, rt);
                    }
                }

                rt.X += 15;
            }

            //绘制节点自身图片                
            if (e.Node.SelectedImageIndex != -1 && this.ImageList != null)
            {
                rt.X += 5;
                e.Graphics.DrawImage(this.ImageList.Images[e.Node.SelectedImageIndex], rt);
            }

            //绘制节点的文本
            rt.X += 20;
            rt.Y += 1;
            rt.Width = this.Width - rt.X;
            e.Graphics.DrawString(e.Node.Text, NodeFont, Brushes.Black, rt);
        }

        #endregion

        #region 鼠标消息响应函数

        //响应鼠标按下消息
        protected override void OnMouseDown(MouseEventArgs e)
        {
            TreeNode clickedNode = this.GetNodeAt(e.X, e.Y);

            if (clickedNode != null && NodeBounds(clickedNode).Contains(e.X, e.Y))
            {
                this.SelectedNode = clickedNode;                
            }
        }

        //响应鼠标双击消息
        protected override void OnMouseDoubleClick(MouseEventArgs e)
        {
            TreeNode clickedNode = this.GetNodeAt(e.X, e.Y);

            if (clickedNode != null && NodeBounds(clickedNode).Contains(e.X, e.Y))
            {
                this.SelectedNode = clickedNode;

                //判断节点的状态
                if (clickedNode.Nodes.Count != 0)
                {
                    if (clickedNode.IsExpanded)
                    {
                        clickedNode.Collapse();
                    }
                    else
                    {
                        clickedNode.Expand();
                    }
                }
            }
        }

        #endregion

        #region 私有函数

        //返回TreeView中TreeNode的整行区域
        private Rectangle NodeBounds(TreeNode node)
        {
            // Set the return value to the normal node bounds.
            Rectangle bounds = node.Bounds;

            //if (node.Tag != null)
            //{
            //    // Retrieve a Graphics object from the TreeView handle
            //    // and use it to calculate the display width of the tag.
            //    Graphics g = this.CreateGraphics();
            //    int tagWidth = (int)g.MeasureString(node.Tag.ToString(), NodeFont).Width + 6;

            //    // Adjust the node bounds using the calculated value.
            //    bounds.Offset(tagWidth / 2, 0);
            //    bounds = Rectangle.Inflate(bounds, tagWidth / 2, 0);
            //    g.Dispose();
            //}

            bounds.Width = this.Width;

            return bounds;
        }

        #endregion

        #region 引用函数

        const int TV_FRIST = 0x1100;
        const int TVM_SETITEMHEIGHT = TV_FRIST + 27;

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        private static extern IntPtr SendMessage(IntPtr hWnd, int nMsg, int wParam, int Param);

        #endregion
    }
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using SenseTreeView.Properties;

namespace SenseTreeView
{
    public partial class Form1 : Form
    {
        private SenseTreeView stv;

        public Form1()
        {
            InitializeComponent();

            // Create and initialize the TreeView control.
            stv = new SenseTreeView();
            stv.Dock = DockStyle.Left;
            stv.BackColor = Color.White;
            //stv.CheckBoxes = true;
            stv.Width = 250;

            ImageList imagelist = new ImageList();
            imagelist.Images.Add(Resources._1264);
            imagelist.Images.Add(Resources._1265);
            imagelist.Images.Add(Resources._1268);
            stv.ImageList = imagelist;

            stv.NodeExpandedImage = Resources.UnSelect;
            stv.NodeCollapseImage = Resources.IsSelect;

            // Add nodes to the TreeView control.            
            for (int x = 1; x < 4; ++x)
            {
                // Add a root node to the TreeView control.                
                TreeNode node = new TreeNode("*");
                node.SelectedImageIndex = 0;
                for (int y = 1; y < 4; ++y)
                {
                    // Add a child node to the root node.
                    TreeNode tn = new TreeNode("Subtask");
                    tn.SelectedImageIndex = 2;
                    node.Nodes.Add(tn);
                }
                stv.Nodes.Add(node);
            }
            stv.ExpandAll();

            // Initialize the form and add the TreeView control to it.            
            this.Controls.Add(stv);
        }
    }
}

效果图:

 

WinForm的TreeView实现Win7 Areo效果

怎么样,效果非常库吧?

WinForm的TreeView实现Win7 Areo效果,布布扣,bubuko.com

WinForm的TreeView实现Win7 Areo效果

上一篇:Windows8 64位运行Silverlight程序不能访问WCF的解决方案


下一篇:一个室内VR渲染教程