如何更改我的treeView图标+, – 像c#.net win窗体中的Windows资源管理器树视图
如何在ShowPlusMinus
和/或ShowRootLines
为true
时显示的加号(+)和减号( – )图像中更改展开/折叠图像。
为了帮助可视化,我想制作以下TreeView
看起来像这样(像Windows资源管理器)
我能想到3种方法:
-
Sunny已经提到过使用
SetWindowTheme(TreeView.Handle, "explorer", null)
-
如果是选项并添加TreeViewItem对象,则使用WPF
-
重写OnPaint方法,这太复杂了,考虑到你只能做1,所以1或2由你决定。
当您想要自定义树视图控件时,Microsoft在treeview控件上提供了一个名为“TreeViewDrawMode”的属性,它的值是一个包含3个值的枚举:Normal,OwnerDrawText,OwnerDrawAll,在您的情况下,您必须使用OwnerDrawAll。 将该属性设置为OwnerDrawAll后,当显示树视图的节点时,将触发名为“DrawNode”的事件,以便您可以在那里处理绘图。 当你自己绘制它时,通常需要绘制3个东西:展开/折叠图标,节点图标,节点文本。 我的示例如下://定义图标文件路径字符串minusPath = Application.StartupPath + Path.DirectorySeparatorChar +“minus.png”; string plusPath = Application.StartupPath + Path.DirectorySeparatorChar +“plus.png”; string nodePath = Application.StartupPath + Path.DirectorySeparatorChar +“directory.png”;
public FrmTreeView() { InitializeComponent(); //setting to customer draw this.treeView1.DrawMode = TreeViewDrawMode.OwnerDrawAll; this.treeView1.DrawNode += new DrawTreeNodeEventHandler(treeView1_DrawNode); } void treeView1_DrawNode(object sender, DrawTreeNodeEventArgs e) { Rectangle nodeRect = e.Node.Bounds; /*--------- 1. draw expand/collapse icon ---------*/ Point ptExpand = new Point(nodeRect.Location.X - 20, nodeRect.Location.Y + 2); Image expandImg = null; if (e.Node.IsExpanded || e.Node.Nodes.Count < 1) expandImg = Image.FromFile(minusPath); else expandImg = Image.FromFile(plusPath); Graphics g = Graphics.FromImage(expandImg); IntPtr imgPtr = g.GetHdc(); g.ReleaseHdc(); e.Graphics.DrawImage(expandImg, ptExpand); /*--------- 2. draw node icon ---------*/ Point ptNodeIcon = new Point(nodeRect.Location.X - 4, nodeRect.Location.Y + 2); Image nodeImg = Image.FromFile(nodePath); g = Graphics.FromImage(nodeImg); imgPtr = g.GetHdc(); g.ReleaseHdc(); e.Graphics.DrawImage(nodeImg, ptNodeIcon); /*--------- 3. draw node text ---------*/ Font nodeFont = e.Node.NodeFont; if (nodeFont == null) nodeFont = ((TreeView)sender).Font; Brush textBrush = SystemBrushes.WindowText; //to highlight the text when selected if ((e.State & TreeNodeStates.Focused) != 0) textBrush = SystemBrushes.HotTrack; //Inflate to not be cut Rectangle textRect = nodeRect; //need to extend node rect textRect.Width += 40; e.Graphics.DrawString(e.Node.Text, nodeFont, textBrush, Rectangle.Inflate(textRect, -12, 0)); }
我的测试结果是这样的:
扩展IvanIčin的解决方案:
[DllImport("uxtheme.dll", ExactSpelling = true, CharSet = CharSet.Unicode)] private static extern int SetWindowTheme(IntPtr hwnd, string pszSubAppName, string pszSubIdList); public static void SetTreeViewTheme(IntPtr treeHandle) { SetWindowTheme(treeHandle, "explorer", null); }
要使用,请在表单和Form_Load
添加TreeView
:
SetTreeViewTheme( treeView1.Handle );
或者,您可以扩展TreeView对象
public class MyTreeView : TreeView { [DllImport("uxtheme.dll", ExactSpelling = true, CharSet = CharSet.Unicode)] private static extern int SetWindowTheme(IntPtr hwnd, string pszSubAppName, string pszSubIdList); public MyTreeView() { SetWindowTheme(this.Handle, "explorer", null); } }
描述调用SetWindowTheme
之前和之后的样子