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

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

问题描述

我想删除 Node.Type 为 5 或 6 的复选框.我使用以下代码:

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?

这是错误的!

推荐答案

在您显示的代码中,您自己处理所有类型为 5 或 6 的节点的绘图.对于其余类型,您只是允许系统以默认方式绘制节点.这就是为什么它们都具有预期的线条,但您自己绘制的线条却没有:您忘记绘制线条了!您看,当您说 e.DrawDefault = false; 时,就假定您确实是认真的.没有做任何常规的绘图,包括标准线.

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.

从您现在拥有的代码来看,您似乎正在尝试在您的自绘代码中尽可能多地模拟系统的本机绘图风格,因此我不清楚您通过自绘代码究竟完成了什么第一名.如果您只是想防止类型 5 和 6 节点的复选框出现(就像线条一样,只是因为您没有绘制它们而没有被绘制!),有一种更简单的方法可以做到这一点,而无需涉及所有者绘图.

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.

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

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

顶部的所有杂乱内容都是您的 P/Invoke 声明.您需要一些常量,TVITEM 结构 描述树视图项的属性,以及 SendMessage功能.底部是您实际调用以执行操作的函数 (HideCheckBox).您只需传入 TreeView 控件和要从中删除复选标记的特定 TreeNode 项.

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天全站免登陆