TreeView删除一些节点的复选框 [英] TreeView Remove CheckBox by some Nodes

查看:336
本文介绍了TreeView删除一些节点的复选框的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  private void TvOne_DrawNode()对象发送者,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;
}
使用(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;
}
}

问题是,根节点不存在。
如何删除复选框,让图像和行在那里?



这是错误的!

解决方案

,你自己为所有类型为5或6的节点处理图形。对于其余类型,你只是允许系统以默认方式绘制节点。这就是为什么他们都有预期的线,但你是所有者 - 绘图不行:你忘了画线!你会看到,当你说 e.DrawDefault = false; 时,它假设你真的意思是。



你需要自己绘制这些线,或者找出没有所有者的方式,



从现在的代码,看起来你想在你的所有者绘制代码中尽可能多地模拟系统的本地绘图风格,所以不清楚我是什么你完成的所有者绘图在第一位。如果你只是试图保持复选框不显示类型5和6节点(这样,就像线,只是没有画,因为你不画他们!),有一个更简单的方法,而不涉及所有者






所以,你问,隐藏单个节点复选框的更简单的方法是什么?好吧,事实证明, TreeView 控件本身实际上支持这一点,但该功能不公开在.NET框架中。你需要P / Invoke并调用Windows API来获取它。将以下代码添加到您的窗体类中(确保您已为 System.Runtime.InteropServices 添加了使用 ):

  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)]
私人结构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>
///在TreeView控件上隐藏指定节点的复选框。
///< / 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 函数。底部是你实际调用的函数来做deed( HideCheckBox )。您只需传递 TreeView 控件和要从中删除复选标记的特定 TreeNode 项。



因此,您可以从每个子节点中删除复选标记,以获取如下所示的内容:



   ; 


I want remove CheckBoxes where the Node.Type is 5 or 6. I use this code:

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;
    }
}

The Problem is that then the Image and the Line to the Root Node is not there. How can Remove the Checkbox and let the Image and the Line there?

This is wrong!

解决方案

In the code you've shown, you are handling the drawing yourself for all of the nodes whose type is either 5 or 6. For the rest of the types, you're simply allowing the system to draw the nodes in the default way. That's why they all have the lines as expected, but the ones you're owner-drawing do not: You forgot to draw in the lines! You see, when you say e.DrawDefault = false; it's assumed that you really do mean it. None of the regular drawing is done, including the standard lines.

You'll either need to draw in those lines yourself, or figure out how to get by without owner-drawing at all.

From the code you have now, it looks like you're trying to simulate the system's native drawing style as much as possible in your owner-draw code, so it's not clear to me what exactly you accomplish by owner-drawing in the first place. If you're just trying to keep checkboxes from showing up for type 5 and 6 nodes (which, like the lines, are simply not getting drawn because you aren't drawing them!), there's a simpler way to do that without involving owner drawing.


So, you ask, what is that simpler way to hide the checkboxes for individual nodes? Well, it turns out that the TreeView control itself actually supports this, but that functionality is not exposed in the .NET Framework. You need to P/Invoke and call the Windows API to get at it. Add the following code to your form class (make sure you've added a using declaration for System.Runtime.InteropServices):

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);
}

All of the messy stuff at the top are your P/Invoke declarations. You need a handful of constants, the TVITEM structure that describes the attributes of a treeview item, and the SendMessage function. At the bottom is the function you'll actually call to do the deed (HideCheckBox). You simply pass in the TreeView control and the particular TreeNode item from which you want to remove the checkmark.

So you can remove the checkmarks from each of the child nodes to get something that looks like this:

   

这篇关于TreeView删除一些节点的复选框的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆