【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);
        }
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM