TreeView通过某些节点删除checkbox

我想删除Node.Type是5或6的CheckBoxes。我使用这个代码:

private void TvOne_DrawNode(object sender, DrawTreeNodeEventArgs e) { int type = (e.Node as Node).typ; if (type == 5 || type == 6) { Color backColor, foreColor; if ((e.State & TreeNodeStates.Selected) == TreeNodeStates.Selected) { backColor = SystemColors.Highlight; foreColor = SystemColors.HighlightText; } else if ((e.State & TreeNodeStates.Hot) == TreeNodeStates.Hot) { backColor = SystemColors.HotTrack; foreColor = SystemColors.HighlightText; } else { backColor = e.Node.BackColor; foreColor = e.Node.ForeColor; } using (SolidBrush brush = new SolidBrush(backColor)) { e.Graphics.FillRectangle(brush, e.Node.Bounds); } TextRenderer.DrawText(e.Graphics, e.Node.Text, this.TvOne.Font, e.Node.Bounds, foreColor, backColor); if ((e.State & TreeNodeStates.Focused) == TreeNodeStates.Focused) { ControlPaint.DrawFocusRectangle(e.Graphics, e.Node.Bounds, foreColor, backColor); } e.DrawDefault = false; } else { e.DrawDefault = true; } } 

问题是,那么图像和根节点的线不在那里。 如何删除checkbox,让图像和线路在那里?

这是错误的!

在你已经显示的代码中,你正在为所有types为5或6的节点自己处理绘图。对于其余的types,你只需要让系统以默认的方式绘制节点。 这就是为什么他们都有预期的线条,但你自己画的那些线条却没有:你忘了画线了! 你看,当你说e.DrawDefault = false; 假设你确实是这个意思。 没有规定的图纸,包括标准的线条。

你可能需要自己画这些线,或者根本不需要绘图。

从你现在的代码中,看起来你试图在你的所有者绘制代码中尽可能地模拟系统的原生绘图风格,所以我不清楚你自己完成了什么, 。 如果你只是试图保持checkbox不显示types5和6节点(像线条一样,因为你没有绘制它们而不会被绘制),所以有一个简单的方法可以做到这一点,而不涉及所有者画画。


所以,你问,隐藏单个节点checkbox的更简单的方法是什么? 那么,事实certificate, TreeView控件本身实际上支持这一点,但该function不在.NET框架中公开。 你需要P / Invoke并调用Windows API来获取它。 将下面的代码添加到您的表单类(确保您已经添加了System.Runtime.InteropServicesusing声明):

 private const int TVIF_STATE = 0x8; private const int TVIS_STATEIMAGEMASK = 0xF000; private const int TV_FIRST = 0x1100; private const int TVM_SETITEM = TV_FIRST + 63; [StructLayout(LayoutKind.Sequential, Pack = 8, CharSet = CharSet.Auto)] private struct TVITEM { public int mask; public IntPtr hItem; public int state; public int stateMask; [MarshalAs(UnmanagedType.LPTStr)] public string lpszText; public int cchTextMax; public int iImage; public int iSelectedImage; public int cChildren; public IntPtr lParam; } [DllImport("user32.dll", CharSet = CharSet.Auto)] private static extern IntPtr SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, ref TVITEM lParam); /// <summary> /// Hides the checkbox for the specified node on a TreeView control. /// </summary> private void HideCheckBox(TreeView tvw, TreeNode node) { TVITEM tvi = new TVITEM(); tvi.hItem = node.Handle; tvi.mask = TVIF_STATE; tvi.stateMask = TVIS_STATEIMAGEMASK; tvi.state = 0; SendMessage(tvw.Handle, TVM_SETITEM, IntPtr.Zero, ref tvi); } 

在顶部的所有杂乱的东西是你的P / Invoke声明。 您需要一些常量,描述树视图项的属性的TVITEM结构和SendMessage函数 。 底部是您实际调用的function( HideCheckBox )。 您只需传入TreeView控件和要从中删除复选标记的特定TreeNode项目。

所以你可以从每个子节点中删除复选标记来获得如下所示的内容:

TreeView隐藏子节点的复选标记

使用TreeViewExtensions。

用法示例:

 private void MyForm_Load(object sender, EventArgs e) { this.treeview1.DrawMode = TreeViewDrawMode.OwnerDrawText; this.treeview1.DrawNode += new DrawTreeNodeEventHandler(arbolDependencias_DrawNode); } void treeview1_DrawNode(object sender, DrawTreeNodeEventArgs e) { if (e.Node.Level == 1) e.Node.HideCheckBox(); e.DrawDefault = true; } 

这里是答案的代码作为扩展方法,使用这个你可以做:

 public static class TreeViewExtensions { private const int TVIF_STATE = 0x8; private const int TVIS_STATEIMAGEMASK = 0xF000; private const int TV_FIRST = 0x1100; private const int TVM_SETITEM = TV_FIRST + 63; [StructLayout(LayoutKind.Sequential, Pack = 8, CharSet = CharSet.Auto)] private struct TVITEM { public int mask; public IntPtr hItem; public int state; public int stateMask; [MarshalAs(UnmanagedType.LPTStr)] public string lpszText; public int cchTextMax; public int iImage; public int iSelectedImage; public int cChildren; public IntPtr lParam; } [DllImport("user32.dll", CharSet = CharSet.Auto)] private static extern IntPtr SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, ref TVITEM lParam); /// <summary> /// Hides the checkbox for the specified node on a TreeView control. /// </summary> public static void HideCheckBox(this TreeNode node) { TVITEM tvi = new TVITEM(); tvi.hItem = node.Handle; tvi.mask = TVIF_STATE; tvi.stateMask = TVIS_STATEIMAGEMASK; tvi.state = 0; SendMessage(node.TreeView.Handle, TVM_SETITEM, IntPtr.Zero, ref tvi); } } 

这是非常好的! 我唯一的修改是只传递TreeNode而不是TreeViewHideCheckBox方法。 TreeView可以从TreeNode本身检索:

 TreeView tvw = node.TreeView;