尽可能接近WINDOWS 8的资源管理器效果(这里只模仿它的效果,处理文件功能不包括在内)
 
  1. TREEVIEW可以增加空白并且空白处不能单击
  2. 重绘三角箭头
  3. 重绘选中时的边框和填充色

  4. 重绘失去焦点时选中时的边框和填充色
  5. 重绘光标所在处的节点背景 MOUSE Hover
  6. 闪烁的问题处理 当TREEVIEW大小改变时闪烁很严重
  7. 做到自定义控件
  8. 图片背景
  9. 光标的在不同位置的相关改变
  10. 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 文件已经解决了控件闪烁问题
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 = (-); [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 > ) || ((OS.Version.Major == ) && (OS.Version.Minor == )));
}
} public static bool IsWinVista
{
get
{
OperatingSystem OS = Environment.OSVersion;
return (OS.Platform == PlatformID.Win32NT) && (OS.Version.Major >= );
}
} /// <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) != ;
} /// <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) != ;
}
} 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 + ;
private const int TVM_SETEXTENDEDSTYLE = TV_FIRST + ;
private const int TVS_EX_DOUBLEBUFFER = 0x0004; private void UpdateExtendedStyles()
{
int Style = ; if (DoubleBuffered)
Style |= TVS_EX_DOUBLEBUFFER; if (Style != )
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(, , ));//填充颜色
private Pen pen1 = new Pen(Color.FromArgb(, , ), );//边框颜色 /*2节点被选中 ,TreeView没有焦点*/
private SolidBrush brush2 = new SolidBrush(Color.FromArgb(, , ));
private Pen pen2 = new Pen(Color.FromArgb(, , ), ); /*3 MouseMove的时候 画光标所在的节点的背景*/
private SolidBrush brush3 = new SolidBrush(Color.FromArgb(, , ));
private Pen pen3 = new Pen(Color.FromArgb(, , ), ); private void treeView1_DrawNode(object sender, DrawTreeNodeEventArgs e)
{ #region 1 选中的节点背景=========================================
Rectangle nodeRect = new Rectangle(,
e.Bounds.Top,
e.Bounds.Width - ,
e.Bounds.Height - ); 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) != && 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 - , nodeRect.Top + , , ); // +-号的大小 是9 * 9 if (e.Node.IsExpanded)
e.Graphics.DrawImage(arrowImageList.Images[], plusRect);
else if (e.Node.IsExpanded == false && e.Node.Nodes.Count > )
e.Graphics.DrawImage(arrowImageList.Images[], 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 + ,
e.Node.Bounds.Width + ,
e.Node.Bounds.Height
);
nodeTextRect.Width += ;
nodeTextRect.Height -= ; e.Graphics.DrawString(e.Node.Text,
e.Node.TreeView.Font,
new SolidBrush(Color.Black),
nodeTextRect); //画子节点个数 (111)
if (e.Node.GetNodeCount(true) > )
{
e.Graphics.DrawString(string.Format("({0})", e.Node.GetNodeCount(true)),
new Font("Arial", ),
Brushes.Gray,
nodeTextRect.Right - ,
nodeTextRect.Top + );
} ///*测试用,画文字出现的矩形*/
//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 > )
{
//图标大小16*16
Rectangle imagebox = new Rectangle(
e.Node.Bounds.X - - ,
e.Node.Bounds.Y + ,
,//IMAGELIST IMAGE WIDTH
);//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 < )
index = ;
else if (index > treeView1.ImageList.Images.Count - )
index = ;
e.Graphics.DrawImage(treeView1.ImageList.Images[index], imagebox);
}
currt_X -= ; /*测试 画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; }
}

 

0 Explore TreeView的更多相关文章

  1. Odoo8.0中允许用户动态调整TreeView栏位宽度

    现有的Odoo8.0中TreeView的栏位宽度是固定的,不可以手动调整,通过安装第三方插件后,可以实现手工动态调整. 下载模块安装即可.http://download.csdn.net/detail ...

  2. 怎样制作web版的folder treeview

    文件夹treeview的效果 这样的treeview在实际项目中使用的场景较多. 既然用的多,那就DIY一遍,虽没有面面俱到,但也要将其基本实现完成一遍. 1.先准备图标素材  file.gif,文件 ...

  3. treeview bootstrap 多级下拉树

    bootstrap-treeview.js1是一款强大的树菜单插件,本文演示bootstrap-treeview.js15种不同的调用方法.它可一次性加载数据,也可异步加载.支持Checkbox,se ...

  4. ComboBox中如何嵌套TreeView控件

      在ComboBox中嵌套TreeView控件,有时候我们在设计界面的时候,由于界面设计的需要,我们需要将TreeView控件嵌套在ComboBox中,因为TreeView控件实在是太占用地方了,要 ...

  5. Virtual Treeview 安装以及入门

    Virtual Treeview是一套Delphi下优秀的VCL控件,代码质量高,使用灵活.功能强大.性能非常好,可以用于表达Treeview和表格类数据.它的代码现在托管在google code上. ...

  6. 潜移默化学会WPF(难点控件treeview)--改造TreeView(CheckBox多选择版本),递归绑定数据

    原文:潜移默化学会WPF(难点控件treeview)--改造TreeView(CheckBox多选择版本),递归绑定数据 目前自己对treeview的感慨很多 今天先讲 面对这种 表结构的数据 的其中 ...

  7. delphi 根据数据库结构生成TreeView

    procedure TUIOperate.FillTree(treeview: TTreeView); var   findq: TADOQuery;   node: TTreeNode;     / ...

  8. 操作TreeView(咏南工作室)

    {*******************************************************}{                                           ...

  9. 侧边栏下拉时箭头的旋转动画(treeView控件)

    //点击菜单时箭头旋转 let treeView = document.getElementsByClassName("treeview");//let解决闭包问题 let las ...

随机推荐

  1. poj2478

    比较简单的树形dp; 定义s[i]为节点i的子树节点数和(包括自身):叶子节点s[j]=1; s[i]=signma(s[k])+1 (k是i的孩子) 则i满足的条件是 1.s[k]<=n di ...

  2. jquery serialize()方法的扩展

    Jquery提供的序列化表单方法serialize方法确实方便,但是我在使用的时候发现了一个弊端:当我使用type:“post”进行ajax请求的时候, 这个时候参数data:$("#myf ...

  3. ExtJs双ActionResult共用同一Js文件ID冲突解决方案

    项目使用MVC+ExtJs实现,权限控制是基于Controller下的ActionResult的,有一个页面因参数不同就需要新建两个ActionResult. 不要问我为何是基于页面级,而不是数据级, ...

  4. UVa 201 Squares

    题意: 给出这样一个图,求一共有多少个大小不同或位置不同的正方形. 分析: 这种题一看就有思路,最开始的想法就是枚举正方形的位置,需要二重循环,枚举边长一重循环,判断是否为正方形又需要一重循环,复杂度 ...

  5. CQOI2009中位数图

    原来在vijos上做过,当时根本看不懂 现在看起来这么水…… x记录从b向左连续走比k大的有多少个 y记录从b向右连续走比k大的有多少个 最后根据乘法原理乘一下 不过要加上x[0]+y[0]+1 因为 ...

  6. Azure HDInsight与Hadoop周边系统集成

     Sunwei 9 Dec 2014 1:54 AM 传统的Hadoop系统提供给用户2个非常优秀的框架,MR计算框架和HDFS存储框架,尽管MR已经显得有些老迈而缓慢,但是HDFS还是很多应用系统的 ...

  7. HDU 5317 RGCDQ

    题意:f(i)表示i的质因子个数,给l和r,问在这一区间内f(i)之间任意两个数最大的最大公倍数是多少. 解法:先用筛法筛素数,在这个过程中计算f(i),因为f(i)不会超过7,所以用一个二维数组统计 ...

  8. java jvm学习笔记六(实现写自己的安全管理器)

    安全管理器SecurityManager里设计的内容实在是非常的庞大,它的核心方法就是checkPerssiom这个方法里又调用AccessController的checkPerssiom方法,访问控 ...

  9. 使用asp.net MVC4中的Bundle遇到的问题及解决办法

    背景 之前有过使用MVC3的经验,也建过MVC4的基本样例看过,知道有bundle这么一个方法. 近日想建个网站使用MVC4,但是我觉得在基本样例上改不好,有太多无用的东西,所以就建了一个空白的MVC ...

  10. Javascript/15-1-14

    1.break 语句用于跳出循环.break 语句跳出循环后,会继续执行该循环之后的代码(如果有的话). continue 用于跳过循环中的一个迭代. 2.label:statements 用于直接跳 ...