How to disable a WinForms TreeView node checkbox?

后端 未结 4 734
臣服心动
臣服心动 2020-11-29 08:13

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

4条回答
  •  无人及你
    2020-11-29 09:05

    This is PowerShell version, many thanks for @sam-trost for his life-savior code!

    P/invoke:

    $TypeDefinition = @'
    using System;
    using System.Runtime.InteropServices;
    namespace Win32Functions {
        public class Win32TreeView {
            // 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", SetLastError = true)]
            public 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;
            }
        }
    }
    '@
    
    Add-Type -TypeDefinition $TypeDefinition -PassThru
    

    Event handler:

    $TreeView1_DrawNode = [System.Windows.Forms.DrawTreeNodeEventHandler]{
        #Event Argument: $_ = [System.Windows.Forms.DrawTreeNodeEventArgs]
        if ($null -ne $_.Node) {
    
            # P/invoke hack to hide Node CheckBox
            if ($_.Node.Level -eq 0) {
                Hide-NodeCheckBox($_.Node)
            }
    
            $_.DrawDefault = $true
        }
    }
    

    TreeView:

    $TreeView1.DrawMode = [TreeViewDrawMode]::OwnerDrawText
    $TreeView1.add_DrawNode($TreeView1_DrawNode)
    

    Function:

    function Hide-NodeCheckBox([TreeNode]$node) {
        # P/invoke hack to hide Node CheckBox
        if ($node.TreeView.CheckBoxes) {
            $tvi = [Win32Functions.Win32TreeView+TVITEM]::new()
            $tvi.hItem = $node.Handle
            $tvi.mask = [Win32Functions.Win32TreeView]::TVIF_STATE
            $tvi.stateMask = [Win32Functions.Win32TreeView]::TVIS_STATEIMAGEMASK
            $tvi.state = 0
            [IntPtr]$lparam = [Marshal]::AllocHGlobal([Marshal]::SizeOf($tvi))
            [Marshal]::StructureToPtr($tvi, $lparam, $false)
            [Win32Functions.Win32TreeView]::SendMessage($node.TreeView.Handle, [Win32Functions.Win32TreeView]::TVM_SETITEM, [IntPtr]::Zero, $lparam)
        }
    }
    

提交回复
热议问题