0 Explore TreeView


盡可能接近WINDOWS 8的資源管理器效果(這里只模仿它的效果,處理文件功能不包括在內)
 
  1. TREEVIEW可以增加空白並且空白處不能單擊
  2. 重繪三角箭頭
  3. 重繪選中時的邊框和填充色

  4. 重繪失去焦點時選中時的邊框和填充色
  5. 重繪光標所在處的節點背景 MOUSE Hover
  6. 閃爍的問題處理 當TREEVIEW大小改變時閃爍很嚴重
  7.  
  8. 做到自定義控件
  9. 圖片背景
  10. 光標的在不同位置的相關改變
  11. WINDOWS 8的資源管理器是不顯示水平滾動條
 

 

相關參考
 
 
 
 
 
 
選中的節點顏色
邊框 顏色      102,167,232
填充顏色       209,232,255
 
TREEVIEW失去焦點
邊框 顏色      222,222,222
填充顏色      247,247,247
 
 
光標所在的節點的
邊框 顏色     112,192,231
填充顏色      229,243,251
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
光標的在不同位置的相關改變
 
 
  
 
 
12  TreeViewEx.cs  源碼
 
編譯環境是vs2015 文件已經解決了控件閃爍問題
完整的文件的源碼: http://www.cnblogs.com/xe2011/p/3859801.html

using System.Drawing; using System.Runtime.InteropServices; namespace System.Windows.Forms { public class API { private const int WS_HSCROLL = 0x100000; private const int WS_VSCROLL = 0x200000; private const int GWL_STYLE = (-16); [DllImport("User32.dll")] public static extern IntPtr LoadCursor(IntPtr hInstance, CursorType cursor); [DllImport("user32.dll")] public static extern int GetWindowLong(IntPtr hwnd, int nIndex); [DllImport("user32.dll")] public static extern bool ShowScrollBar(IntPtr hWnd, int wBar, bool bShow); public const int WM_PRINTCLIENT = 0x0318; public const int PRF_CLIENT = 0x00000004; [DllImport("user32.dll")] public static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam); /// <summary>
        /// 顯示系統光標小手 /// 像Win7非經典主題的小手光標 /// </summary>
        public static Cursor Hand { get { IntPtr h = LoadCursor(IntPtr.Zero, CursorType.IDC_HAND); return new Cursor(h); } } public static bool IsWinXP { get { OperatingSystem OS = Environment.OSVersion; return (OS.Platform == PlatformID.Win32NT) && ((OS.Version.Major > 5) || ((OS.Version.Major == 5) && (OS.Version.Minor == 1))); } } public static bool IsWinVista { get { OperatingSystem OS = Environment.OSVersion; return (OS.Platform == PlatformID.Win32NT) && (OS.Version.Major >= 6); } } /// <summary>
        /// 判斷是否出現垂直滾動條 /// </summary>
        /// <param name="ctrl">待測控件</param>
        /// <returns>出現垂直滾動條返回true,否則為false</returns>
        public static bool IsVerticalScrollBarVisible(Control ctrl) { if (!ctrl.IsHandleCreated) return false; return (GetWindowLong(ctrl.Handle, GWL_STYLE) & WS_VSCROLL) != 0; } /// <summary>
        /// 判斷是否出現水平滾動條 /// </summary>
        /// <param name="ctrl">待測控件</param>
        /// <returns>出現水平滾動條返回true,否則為false</returns>
        public static bool IsHorizontalScrollBarVisible(Control ctrl) { if (!ctrl.IsHandleCreated) return false; return (GetWindowLong(ctrl.Handle, GWL_STYLE) & WS_HSCROLL) != 0; } } public enum CursorType : uint { IDC_ARROW = 32512U, IDC_IBEAM = 32513U, IDC_WAIT = 32514U, IDC_CROSS = 32515U, IDC_UPARROW = 32516U, IDC_SIZE = 32640U, IDC_ICON = 32641U, IDC_SIZENWSE = 32642U, IDC_SIZENESW = 32643U, IDC_SIZEWE = 32644U, IDC_SIZENS = 32645U, IDC_SIZEALL = 32646U, IDC_NO = 32648U, //小手
        IDC_HAND = 32649U, IDC_APPSTARTING = 32650U, IDC_HELP = 32651U } public class TreeViewEx : TreeView { #region 雙緩存重繪

        private const int WM_VSCROLL = 0x0115; private const int WM_HSCROLL = 0x0114; //private const int WM_MOUSEWHEEL = 0x020A;
        private const int TV_FIRST = 0x1100; private const int TVM_SETBKCOLOR = TV_FIRST + 29; private const int TVM_SETEXTENDEDSTYLE = TV_FIRST + 44; private const int TVS_EX_DOUBLEBUFFER = 0x0004; private void UpdateExtendedStyles() { int Style = 0; if (DoubleBuffered) Style |= TVS_EX_DOUBLEBUFFER; if (Style != 0) API.SendMessage(Handle, TVM_SETEXTENDEDSTYLE, (IntPtr)TVS_EX_DOUBLEBUFFER, (IntPtr)Style); } protected override void OnHandleCreated(EventArgs e) { base.OnHandleCreated(e); UpdateExtendedStyles(); if (!API.IsWinXP) API.SendMessage(Handle, TVM_SETBKCOLOR, IntPtr.Zero, (IntPtr)ColorTranslator.ToWin32(BackColor)); } protected override void OnPaint(PaintEventArgs e) { if (GetStyle(ControlStyles.UserPaint)) { Message m = new Message(); m.HWnd = Handle; m.Msg = API.WM_PRINTCLIENT; m.WParam = e.Graphics.GetHdc(); m.LParam = (IntPtr)API.PRF_CLIENT; DefWndProc(ref m); e.Graphics.ReleaseHdc(m.WParam); } base.OnPaint(e); } #endregion

        public TreeViewEx() { treeView1 = this; treeView1.HotTracking = true; treeView1.HideSelection = false; treeView1.SelectedImageIndex = treeView1.ImageIndex; this.treeView1.BackColor = System.Drawing.Color.White; this.treeView1.BorderStyle = System.Windows.Forms.BorderStyle.None; this.treeView1.Font = new System.Drawing.Font("微軟雅黑", 9.7F); this.treeView1.FullRowSelect = true; treeView1.DrawMode = TreeViewDrawMode.OwnerDrawAll; //treeView1.Nodes[1].Expand(); //treeView1.Nodes[5].Expand(); //treeView1.SelectedNode = treeView1.Nodes[1];


            this.treeView1.DrawNode += new System.Windows.Forms.DrawTreeNodeEventHandler(this.treeView1_DrawNode); this.treeView1.BeforeSelect += new System.Windows.Forms.TreeViewCancelEventHandler(this.treeView1_BeforeSelect); this.treeView1.KeyDown += new System.Windows.Forms.KeyEventHandler(this.treeView1_KeyDown); } #region DrawNode

        public ImageList arrowImageList { get { return arrowImageList1; } set { arrowImageList1 = value; } } /*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); private void treeView1_DrawNode(object sender, DrawTreeNodeEventArgs e) { #region 1     選中的節點背景========================================= Rectangle nodeRect = new Rectangle(1, e.Bounds.Top, e.Bounds.Width - 3, e.Bounds.Height - 1); if (e.Node.IsSelected) { //TreeView有焦點的時候 畫選中的節點
                if (treeView1.Focused) { e.Graphics.FillRectangle(brush1, nodeRect); e.Graphics.DrawRectangle(pen1, nodeRect); /*測試 畫聚焦的邊框*/
                    //ControlPaint.DrawFocusRectangle(e.Graphics, e.Bounds, Color.Black, SystemColors.Highlight);
 } /*TreeView失去焦點的時候 */
                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 + 7, 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 + 2, 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 (treeView1.ImageList != null && treeView1.ImageList.Images.Count > 0) { //圖標大小16*16
                Rectangle imagebox = new Rectangle( e.Node.Bounds.X - 3 - 16, e.Node.Bounds.Y + 3, 16,//IMAGELIST IMAGE WIDTH
                    16);//HEIGHT


                int index = e.Node.ImageIndex; string imagekey = e.Node.ImageKey; if (imagekey != "" && treeView1.ImageList.Images.ContainsKey(imagekey)) e.Graphics.DrawImage(treeView1.ImageList.Images[imagekey], imagebox); else { if (e.Node.ImageIndex < 0) index = 0; else if (index > treeView1.ImageList.Images.Count - 1) index = 0; e.Graphics.DrawImage(treeView1.ImageList.Images[index], imagebox); } currt_X -= 19; /*測試 畫IMAGELIST的矩形*/
                //if (e.Node.ImageIndex > 0) // e.Graphics.DrawRectangle(new Pen(Color.Black, 1), imagebox);
 } #endregion

            ///*測試 畫所有的邊框*/
            //nodeRect = new Rectangle(1, // e.Bounds.Top + 1, // e.Bounds.Width - 3, // e.Bounds.Height - 2); //e.Graphics.DrawRectangle(new Pen(Color.Gray), nodeRect);
 } #endregion


        private void treeView1_BeforeSelect(object sender, TreeViewCancelEventArgs e) { if (e.Node != null) { //禁止選中空白項
                if (e.Node.Text == "") { //響應上下鍵
                    if (ArrowKeyUp) { if (e.Node.PrevNode != null && e.Node.PrevNode.Text != "") treeView1.SelectedNode = e.Node.PrevNode; } if (ArrowKeyDown) { if (e.Node.NextNode != null && e.Node.NextNode.Text != "") treeView1.SelectedNode = e.Node.NextNode; } e.Cancel = true; } } } private void treeView1_KeyDown(object sender, KeyEventArgs e) { ArrowKeyUp = (e.KeyCode == Keys.Up); if (e.KeyCode == Keys.Down) { Text = "Down"; } ArrowKeyDown = (e.KeyCode == Keys.Down); if (e.KeyCode == Keys.Up) { Text = "UP"; } } private bool ArrowKeyUp = false; private bool ArrowKeyDown = false; private System.Windows.Forms.ImageList arrowImageList1; private TreeView treeView1; } }

 


 




免責聲明!

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



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