📄 treeviewex.cs
字号:
namespace feiyun0112.cnblogs.com.CSDNReader.Controls
{
using System;
using System.Drawing;
using System.Runtime.CompilerServices;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
public class TreeViewEx : TreeView
{
private int _updateCount;
private const int CCM_FIRST = 0x2000;
private const int CCM_SETVERSION = 0x2007;
private const int CDDS_ITEMPREPAINT = 0x10001;
private const int CDRF_NOTIFYSUBITEMDRAW = 0x20;
private const int NM_CUSTOMDRAW = -12;
private const int NM_FIRST = 0;
private const int OCM_NOTIFY = 0x204e;
[StructLayout(LayoutKind.Sequential)]
internal struct NMCUSTOMDRAW
{
public NMHDR hdr;
public int dwDrawStage;
public IntPtr hdc;
public Rectangle rc;
public int dwItemSpec;
public int uItemState;
public IntPtr lItemlParam;
}
[StructLayout(LayoutKind.Sequential)]
internal struct NMHDR
{
public IntPtr hwndFrom;
public int idfrom;
public int code;
}
public delegate string DelegateGetNodeInfo(TreeNode node);
public event DelegateGetNodeInfo GetNodeInfo;
public void BeginUpdate()
{
base.BeginUpdate();
this._updateCount++;
}
private void BuildState(TreeNode node, StringBuilder sb)
{
if (node.IsSelected)
{
sb.Append('S');
}
if (!node.IsExpanded)
{
sb.Append('-');
}
else
{
sb.Append('+');
foreach (TreeNode n in node.Nodes)
{
this.BuildState(n, sb);
}
}
}
public void EndUpdate()
{
if (this._updateCount > 0)
{
this._updateCount--;
}
base.EndUpdate();
}
public string GetState()
{
StringBuilder sb = new StringBuilder();
this.BuildState(base.Nodes[0], sb);
return sb.ToString();
}
protected override void OnCreateControl()
{
base.OnCreateControl();
Message msg = Message.Create(base.Handle, 0x2007, new IntPtr(5), IntPtr.Zero);
this.DefWndProc(ref msg);
}
public void RestoreState(string state)
{
if (state != null)
{
int index = 0;
this.RestoreState(state, ref index, base.Nodes[0]);
if (base.SelectedNode != null)
{
base.SelectedNode.EnsureVisible();
}
}
}
private void RestoreState(string state, ref int stateIndex, TreeNode node)
{
if (stateIndex < state.Length)
{
char c = state[stateIndex++];
switch (c)
{
case 'S':
base.SelectedNode = node;
c = state[stateIndex++];
break;
case '-':
node.Collapse();
return;
}
if (c == '+')
{
node.Expand();
foreach (TreeNode n in node.Nodes)
{
this.RestoreState(state, ref stateIndex, n);
}
}
}
}
public void TreeViewPaintNodeInfo(Rectangle rc)
{
if (rc != Rectangle.Empty)
{
TreeNode node = base.GetNodeAt(rc.Location.X + 1, rc.Location.Y + 1);
if ((node != null) && !node.IsEditing)
{
string strText = this.GetNodeInfo(node);
if (strText != null)
{
long relXpos = node.Bounds.X + node.Bounds.Width;
long xpos = rc.X + relXpos;
long ypos = rc.Y;
Brush brush = new SolidBrush(this.BackColor);
using (Graphics g = Graphics.FromHwnd(base.Handle))
{
g.FillRectangle(brush, (float)xpos, (float)ypos, (float)(base.Width - relXpos), (float)node.Bounds.Height);
g.DrawString(" (" + strText + ")", this.Font, Brushes.Blue, (float)xpos, (float)ypos, StringFormat.GenericTypographic);
}
}
}
}
}
protected override void WndProc(ref Message m)
{
if (((m.Msg == 0x204e) && (this.GetNodeInfo != null)) && (this._updateCount == 0))
{
NMHDR hdr = (NMHDR)m.GetLParam(typeof(NMHDR));
if ((hdr.code == -12) && (hdr.hwndFrom == base.Handle))
{
NMCUSTOMDRAW customDraw = (NMCUSTOMDRAW)m.GetLParam(typeof(NMCUSTOMDRAW));
if (customDraw.dwDrawStage == 0x10001)
{
this.TreeViewPaintNodeInfo(customDraw.rc);
m.Result = IntPtr.Zero;
}
else
{
m.Result = (IntPtr)0x20;
}
}
}
base.WndProc(ref m);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -