2014-03-18 52 views
0

我用以下解决方案来显示或隐藏在一个TreeView复选框:的WinForms TreeView控件:检查是否复选框被隐藏

https://stackoverflow.com/a/22230299/1583649

不过,现在我想知道如何检查,如果该复选框隐藏或不为节点。

例如,我希望能够将checkbox.checked设置为true(或false),只有当顶层节点被选中时,复选框可见的顶级节点的子节点。有没有办法做到这一点?

+0

这些都不是必要的。只需使用TreeNode.StateImageIndex属性即可。将其设置为-1以隐藏假复选框,将其设置为0或1以选择其中一个状态图像。读回来当然也是微不足道的。 –

+0

等待你是否说我不需要用户Interop来隐藏复选框本身? – MaxOvrdrv

+0

我试了你的答案汉斯,它根本没有工作...对不起。 – MaxOvrdrv

回答

2

可以使用TVM_GETITEM或TVM_GETITEMSTATE来获取状态,然后可以使用该状态来推断节点上的哪个复选框图像(none,checked或unchecked)。这里有一个扩展类,它提供了你需要的两种方法。

用法:

// something like this 
var treeNode = ...; 
if (treeNode.IsCheckBoxVisible()) 
    treeNode.SetIsCheckBoxVisible(false); 
else 
    treeNode.SetIsCheckBoxVisible(true); 

扩展:

public static class TreeViewExtensions 
{ 
    /// <summary> 
    /// Gets a value indicating if the checkbox is visible on the tree node. 
    /// </summary> 
    /// <param name="node">The tree node.</param> 
    /// <returns><value>true</value> if the checkbox is visible on the tree node; otherwise <value>false</value>.</returns> 
    public static bool IsCheckBoxVisible(this TreeNode node) 
    { 
     if (node == null) 
      throw new ArgumentNullException("node"); 
     if (node.TreeView == null) 
      throw new InvalidOperationException("The node does not belong to a tree."); 
     var tvi = new TVITEM 
      { 
       hItem = node.Handle, 
       mask = TVIF_STATE 
      }; 
     var result = SendMessage(node.TreeView.Handle, TVM_GETITEM, node.Handle, ref tvi); 
     if (result == IntPtr.Zero) 
      throw new ApplicationException("Error getting TreeNode state."); 
     var imageIndex = (tvi.state & TVIS_STATEIMAGEMASK) >> 12; 
     return (imageIndex != 0); 
    } 

    /// <summary> 
    /// Sets a value indicating if the checkbox is visible on the tree node. 
    /// </summary> 
    /// <param name="node">The tree node.</param> 
    /// <param name="value"><value>true</value> to make the checkbox visible on the tree node; otherwise <value>false</value>.</param> 
    public static void SetIsCheckBoxVisible(this TreeNode node, bool value) 
    { 
     if (node == null) 
      throw new ArgumentNullException("node"); 
     if (node.TreeView == null) 
      throw new InvalidOperationException("The node does not belong to a tree."); 
     var tvi = new TVITEM 
      { 
       hItem = node.Handle, 
       mask = TVIF_STATE, 
       stateMask = TVIS_STATEIMAGEMASK, 
       state = (value ? node.Checked ? 2 : 1 : 0) << 12 
      }; 
     var result = SendMessage(node.TreeView.Handle, TVM_SETITEM, IntPtr.Zero, ref tvi); 
     if (result == IntPtr.Zero) 
      throw new ApplicationException("Error setting TreeNode state."); 
    } 

    private const int TVIF_STATE = 0x8; 
    private const int TVIS_STATEIMAGEMASK = 0xF000; 
    private const int TV_FIRST = 0x1100; 
    private const int TVM_GETITEM = TV_FIRST + 62; 
    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); 
} 
+0

谢谢!很棒! – MaxOvrdrv