locked
Unable to remove checkbox in front of parent node - treeView RRS feed

  • Question

  • I'm trying to hide the checkbox infront of all my parent nodes in my treeview, but I can't get it to work.  I also tried to modify the color of the text and background but that does not work either.  I tried placing the call to the function in the form load, also in the contructor. Here is the functions I am trying to call

    //Hide Checkbox

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

    This is how I was colling it (in the constructor of my form)

    foreach (TreeNode tn in treeView1.Nodes)
                {
                    // if the text properties match, color the item 
    
                    if (tn.Text == "NODE0")
                    {
                        tn.BackColor = Color.Yellow;
                        HideCheckBox(this.treeView1, tn);
                    }
                } 

    Sunday, February 26, 2012 6:07 PM

Answers

  • Hi sjs1978,

    Do you mean to hide the checkboxes for certain nodes(Level ==0)? 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 it, and handle the drawing in the DrawNode event. But before that you need to set our tree to be set as owner drawn in order for this event, so you need to set this.treeView1.DrawMode = TreeViewDrawMode.OwnerDrawText; 

    And then, 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); 
    
    At last, in your treeView.DrawNode event 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:
    private void treeView1_DrawNode(object sender, DrawTreeNodeEventArgs e)
            {
                if (e.Node.Level == 1)
                    HideCheckBox(treeView1,e.Node);
                e.DrawDefault = true; 
            } 

    For more information you can refer to http://stackoverflow.com/questions/4826556/treeview-remove-checkbox-by-some-nodes 

    Regards,

    Helen Zhou [MSFT]
    MSDN Community Support | Feedback to us

    • Marked as answer by Helen Zhou Thursday, March 8, 2012 5:47 AM
    Wednesday, February 29, 2012 6:49 AM

All replies

  • Hi sjs1978,

    Do you mean to hide the checkboxes for certain nodes(Level ==0)? 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 it, and handle the drawing in the DrawNode event. But before that you need to set our tree to be set as owner drawn in order for this event, so you need to set this.treeView1.DrawMode = TreeViewDrawMode.OwnerDrawText; 

    And then, 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); 
    
    At last, in your treeView.DrawNode event 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:
    private void treeView1_DrawNode(object sender, DrawTreeNodeEventArgs e)
            {
                if (e.Node.Level == 1)
                    HideCheckBox(treeView1,e.Node);
                e.DrawDefault = true; 
            } 

    For more information you can refer to http://stackoverflow.com/questions/4826556/treeview-remove-checkbox-by-some-nodes 

    Regards,

    Helen Zhou [MSFT]
    MSDN Community Support | Feedback to us

    • Marked as answer by Helen Zhou Thursday, March 8, 2012 5:47 AM
    Wednesday, February 29, 2012 6:49 AM
  • Perfect!

    In VB:

        Private Const TVIF_STATE As Integer = &H8
        Private Const TVIS_STATEIMAGEMASK As Integer = &HF000
        Private Const TV_FIRST As Integer = &H1100
        Private Const TVM_SETITEM As Integer = TV_FIRST + 63

        <Runtime.InteropServices.StructLayout(LayoutKind.Sequential, Pack:=8, CharSet:=CharSet.Auto)> _
        Private Structure TVITEM
            Public mask As Integer
            Public hItem As IntPtr
            Public state As Integer
            Public stateMask As Integer
            <MarshalAs(UnmanagedType.LPTStr)> _
            Public lpszText As String
            Public cchTextMax As Integer
            Public iImage As Integer
            Public iSelectedImage As Integer
            Public cChildren As Integer
            Public lParam As IntPtr
        End Structure

        <DllImport("user32.dll", CharSet:=CharSet.Auto)> _
        Private Shared Function SendMessage(hWnd As IntPtr, Msg As Integer, wParam As IntPtr, ByRef lParam As TVITEM) As IntPtr
        End Function

        ''' <summary>
        ''' Hides the checkbox for the specified node on a TreeView control.
        ''' </summary>
        Private Sub HideCheckBox(tvw As TreeView, node As TreeNode)
            Dim tvi As New TVITEM()
            tvi.hItem = node.Handle
            tvi.mask = TVIF_STATE
            tvi.stateMask = TVIS_STATEIMAGEMASK
            tvi.state = 0
            SendMessage(tvw.Handle, TVM_SETITEM, IntPtr.Zero, tvi)
        End Sub

    And for the drawnode event:

                HideCheckBox(leftTree, e.Node)
                e.DrawDefault = True

    Friday, January 31, 2014 8:24 AM
  • This works great!  I was not, however, required to change the DrawMode of the treeview.  Just calling the SendMessage works perfect!.  I was wondering if there is a TVITEM structure that I can use with SendMessage to display a checkbox that was hidden with an earlier call.

    If this is not possible can I enable and disable them?  

    Thanks

    Thursday, October 13, 2016 2:48 PM