我使用以下解决方案在TreeView中显示或隐藏复选框:
https://stackoverflow.com/a/22230299/1583649
但是,现在我想知道如何检查节点是否隐藏了复选框。
例如,我希望能够仅在顶级节点的子节点上将checkbox.checked设置为true(或false),该节点在选中顶级节点时可以看到复选框。有没有办法做到这一点?
答案 0 :(得分:2)
TVM_GETITEM或TVM_GETITEMSTATE可用于获取状态,然后可用于推断节点上的哪个复选框图像(无,已选中或未选中)。这是一个扩展类,它提供了您需要的两种方法。
用法:
// something like this
var treeNode = ...;
if (treeNode.IsCheckBoxVisible())
treeNode.SetIsCheckBoxVisible(false);
else
treeNode.SetIsCheckBoxVisible(true);
EXTENSIONS:
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);
}