using System.Drawing;
using System.Runtime.InteropServices;
using System.Reflection;
using System.Drawing.Drawing2D;
namespace System.Windows.Forms
{
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()
{
typeof(Control).GetProperty("DoubleBuffered", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(treeView1, true, null);
}
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);
treeView1.DrawMode = TreeViewDrawMode.OwnerDrawAll;
this.treeView1.FullRowSelect = true;
this.treeView1.ShowLines = false;
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;
}
}
public Color SelectColor
{
get
{
return m_SelectColor;
}
set
{
m_SelectColor = value;
m_SelectColorBrush = new SolidBrush(Color.FromArgb(100, m_SelectColor.R, m_SelectColor.G, m_SelectColor.B));
//Color ex = Color.FromArgb(100, m_SelectColor.R, m_SelectColor.G, m_SelectColor.B);
//m_SelectColorBrushxx = new LinearGradientBrush(this.ClientRectangle,m_SelectColor,ex,LinearGradientMode.ForwardDiagonal);
m_SelectPen = new Pen(m_SelectColor);
}
}
public Color SelectColor2
{
get
{
return m_SelectColor2;
}
set
{
m_SelectColor2 = value;
m_SelectColorBrush2 = new SolidBrush(Color.FromArgb(100, m_SelectColor2.R,m_SelectColor2.G, m_SelectColor2.B));
//Color ex = Color.FromArgb(100, m_SelectColor2.R, m_SelectColor2.G, m_SelectColor2.B);
//m_SelectColorBrushxx2 = new LinearGradientBrush(this.ClientRectangle, m_SelectColor2, ex, LinearGradientMode.ForwardDiagonal);
m_SelectPen2 = new Pen(m_SelectColor2);
}
}
public Color ColorEx
{
get
{
return m_Color;
}
set
{
m_Color = value;
m_ColorBrush = new SolidBrush(Color.FromArgb(100,m_Color.R, m_Color.G, m_Color.B));
//Color ex = Color.FromArgb(100, m_Color.R, m_Color.G, m_Color.B);
//m_ColorBrushxx = new LinearGradientBrush(this.ClientRectangle, m_Color, ex, LinearGradientMode.ForwardDiagonal);
m_Pen = new Pen(m_Color);
}
}
private SolidBrush m_SelectColorBrush;
//private Brush m_SelectColorBrushxx;
private SolidBrush m_SelectColorBrush2;
//private Brush m_SelectColorBrushxx2;
private SolidBrush m_ColorBrush;
//private Brush m_ColorBrushxx;
private Pen m_SelectPen;
private Pen m_SelectPen2;
private Pen m_Pen;
/*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(SystemColors.ControlLight, 1);
/*3 MouseMove的时候 画光标所在的节点的背景*/
private SolidBrush brush3 = new SolidBrush(Color.AliceBlue); // 鼠标停止
private Pen pen3 = new Pen(SystemColors.ControlLight, 1); // 选中
private void treeView1_DrawNode(object sender, DrawTreeNodeEventArgs e)
{
try
{
//if (BackColorBrush == null)
//{
// BackColorBrush = new SolidBrush(treeView1.BackColor);
//}
SolidBrush BackColorBrush = new SolidBrush(treeView1.BackColor);
Rectangle nodeRect = new Rectangle(2, e.Bounds.Top, e.Bounds.Width - 5, e.Bounds.Height-1);
#region 1 选中的节点背景=========================================
if (e.Node.IsSelected)
{
//TreeView有焦点的时候 画选中的节点
//if (treeView1.Focused)
if(e.State != (TreeNodeStates.Focused|TreeNodeStates.Selected))
{
if (m_SelectColor != null)
{
e.Graphics.FillRectangle(m_SelectColorBrush, nodeRect);
//e.Graphics.DrawRectangle(m_SelectPen, nodeRect);
}
else
{
e.Graphics.FillRectangle(brush1, nodeRect);
//e.Graphics.DrawRectangle(pen1, nodeRect);
}
/*测试 画聚焦的边框*/
ControlPaint.DrawFocusRectangle(e.Graphics, nodeRect, Color.Black, SystemColors.Highlight);
}
/*TreeView失去焦点的时候 */
else
{
if (m_SelectColor2 != null)
{
e.Graphics.FillRectangle(m_SelectColorBrush2, nodeRect);
//e.Graphics.DrawRectangle(m_SelectPen2, 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)
{
if (ColorEx != null)
{
e.Graphics.FillRectangle(m_ColorBrush, nodeRect);
e.Graphics.DrawRectangle(m_Pen, nodeRect);
}
else
{
e.Graphics.FillRectangle(brush3, nodeRect);
e.Graphics.DrawRectangle(pen3, nodeRect);
}
}
else
{
e.Graphics.FillRectangle(BackColorBrush, e.Bounds);
}
#endregion
#region 2 +-号绘制=========================================
Rectangle plusRect;
if (treeView1.ImageList != null)
{
plusRect = new Rectangle(e.Node.Bounds.Left - 32, nodeRect.Top + 7, 9, 9); // +-号的大小 是9 * 9
}
else
{
plusRect = new Rectangle(e.Node.Bounds.Left - 20, 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);
#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(false)),
// new Font("Arial", 8),
// Brushes.Gray,
// nodeTextRect.Right - 4,
// nodeTextRect.Top + 2);
//}
#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;
}
#endregion
}
catch(Exception ex)
{
}
}
#endregion
//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 void treeView1_BeforeSelect(object sender, TreeViewCancelEventArgs e)
{
try
{
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;
}
}
}
catch(Exception ex)
{
}
}
private bool ArrowKeyUp = false;
private bool ArrowKeyDown = false;
private System.Windows.Forms.ImageList arrowImageList1;
private Color m_SelectColor;
private Color m_SelectColor2;
private Color m_Color;
private TreeView treeView1;
}
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);
///
/// 显示系统光标小手
/// 像Win7非经典主题的小手光标
///
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);
}
}
///
/// 判断是否出现垂直滚动条
///
/// 待测控件
/// 出现垂直滚动条返回true,否则为false
public static bool IsVerticalScrollBarVisible(Control ctrl)
{
if (!ctrl.IsHandleCreated)
return false;
return (GetWindowLong(ctrl.Handle, GWL_STYLE) & WS_VSCROLL) != 0;
}
///
/// 判断是否出现水平滚动条
///
/// 待测控件
/// 出现水平滚动条返回true,否则为false
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
}
}