如何禁用 WinForms TreeView 节点复选框? [英] How to disable a WinForms TreeView node checkbox?

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

问题描述

我需要能够禁用 WinForms 应用程序的 TreeView 控件中的某些复选框,但标准 TreeView 控件没有内置此类功能.

I need to be able to disable some of the checkboxes in a TreeView control of a WinForms application, but there's no such functionality built-in to the standard TreeView control.

我已经在使用 TreeView.BeforeCheck 事件,如果节点被禁用,则取消它并且工作正常.

I am already using the TreeView.BeforeCheck event and cancel it if the node is disabled and that works perfectly fine.

我还将禁用节点的 ForeColor 更改为 GrayText.

I also change the ForeColor of the disabled nodes to GrayText.

有没有人有一个简单而强大的解决方案?

Does anyone have a simple and robust solution?

推荐答案

由于在 C++ 中有支持,我们可以使用 p/invoke 解决它.

Since there's support in C++ we can resolve it using p/invoke.

这是 p/invoke 部分的设置,只需将其提供给调用类即可.

Here's the setup for the p/invoke part, just make it available to the calling class.

    // constants used to hide a checkbox
    public const int TVIF_STATE = 0x8;
    public const int TVIS_STATEIMAGEMASK = 0xF000;
    public const int TV_FIRST = 0x1100;
    public const int TVM_SETITEM = TV_FIRST + 63;

    [DllImport("user32.dll")]
    static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam,
    IntPtr lParam); 

    // struct used to set node properties
    public 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;

    } 

我们想逐个节点地确定.最简单的方法是在绘制节点事件上.为了这个事件,我们必须将我们的树设置为所有者绘制,因此请确保将其设置为默认设置以外的其他设置.

We want to determine on a node by node basis. The easiest way to do that is on the draw node event. We have to set our tree to be set as owner drawn in order for this event, so be sure to set that to something other than the default setting.

this.tree.DrawMode = TreeViewDrawMode.OwnerDrawText;
this.tree.DrawNode += new DrawTreeNodeEventHandler(tree_DrawNode);

在您的 tree_DrawNode 函数中,确定正在绘制的节点是否应该有一个复选框,并在合适时隐藏它.然后将 Default Draw 属性设置为 true,因为我们不想担心绘制所有其他细节.

In your tree_DrawNode function determine if the node being drawn is supposed to have a checkbox, and hide it when approriate. Then set the Default Draw property to true since we don't want to worry about drawing all the other details.

void tree_DrawNode(object sender, DrawTreeNodeEventArgs e)
{
    if (e.Node.Level == 1)
    {
        HideCheckBox(e.Node);
        e.DrawDefault = true;
    }
    else 
    {
        e.Graphics.DrawString(e.Node.Text, e.Node.TreeView.Font,
           Brushes.Black, e.Node.Bounds.X, e.Node.Bounds.Y);
    }
}

最后,对我们定义的函数的实际调用:

Lastly, the actual call to the function we defined:

private void HideCheckBox(TreeNode node)
{
    TVITEM tvi = new TVITEM();
    tvi.hItem = node.Handle;
    tvi.mask = TVIF_STATE;
    tvi.stateMask = TVIS_STATEIMAGEMASK;
    tvi.state = 0;
    IntPtr lparam = Marshal.AllocHGlobal(Marshal.SizeOf(tvi));
    Marshal.StructureToPtr(tvi, lparam, false);
    SendMessage(node.TreeView.Handle, TVM_SETITEM, IntPtr.Zero, lparam);
}

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

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