C# WinForms树视图:检查复选框是否隐藏
我使用以下解决方案在树状视图中显示或隐藏复选框: 但是,现在我想知道如何检查节点的复选框是否隐藏C# WinForms树视图:检查复选框是否隐藏,c#,treeview,winforms-interop,C#,Treeview,Winforms Interop,我使用以下解决方案在树状视图中显示或隐藏复选框: 但是,现在我想知道如何检查节点的复选框是否隐藏 例如,我希望能够仅在顶级节点的子节点上将checkbox.checked设置为true(或false),该顶级节点在选中顶级节点时具有可见的复选框。有没有办法做到这一点?TVM\u GETITEM或TVM\u GETITEMSTATE可用于获取状态,然后可用于推断节点上有哪个复选框图像(无、选中或未选中)。这里有一个扩展类,它提供了您需要的两种方法 用法: // something like th
例如,我希望能够仅在顶级节点的子节点上将checkbox.checked设置为true(或false),该顶级节点在选中顶级节点时具有可见的复选框。有没有办法做到这一点?TVM\u GETITEM或TVM\u GETITEMSTATE可用于获取状态,然后可用于推断节点上有哪个复选框图像(无、选中或未选中)。这里有一个扩展类,它提供了您需要的两种方法 用法:
// 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);
}
公共静态类TreeViewExtensions
{
///
///获取一个值,该值指示复选框在树节点上是否可见。
///
///树节点。
///如果复选框在树节点上可见,则为true;否则为false。
公共静态bool IsCheckBoxVisible(此树节点)
{
if(node==null)
抛出新的ArgumentNullException(“节点”);
if(node.TreeView==null)
抛出新的InvalidOperationException(“节点不属于树”);
var tvi=新的tvi项目
{
hItem=node.Handle,
掩码=TVIF_状态
};
var result=SendMessage(node.TreeView.Handle,TVM_GETITEM,node.Handle,ref-tvi);
如果(结果==IntPtr.Zero)
抛出新的ApplicationException(“获取TreeNode状态时出错”);
var imageIndex=(tvi.state和TVIS_stateMageMask)>>12;
返回值(imageIndex!=0);
}
///
///设置一个值,该值指示复选框是否在树节点上可见。
///
///树节点。
///如果为true,则复选框在树节点上可见;否则为false。
公共静态void SetIsCheckBoxVisible(此树节点,布尔值)
{
if(node==null)
抛出新的ArgumentNullException(“节点”);
if(node.TreeView==null)
抛出新的InvalidOperationException(“节点不属于树”);
var tvi=新的tvi项目
{
hItem=node.Handle,
掩码=TVIF_状态,
stateMask=TVIS\U StateMageMask,
状态=(值?节点。已检查?2:1:0)这些都不是必需的。只需使用TreeNode.StateImageIndex属性。将其设置为-1可隐藏假复选框,将其设置为0或1可选择其中一个状态图像。现在将其读回当然也很简单。等等,你是说我不需要用户互操作来隐藏复选框本身吗?我尝试了你的答案,但根本不起作用。。。很抱歉