.net winform下TreeNode在没有子结点时也显示+号的解决办法
TreeNode竟然没有HasChildren属性,ft!
今天写程序时遇到这个问题,找了msdn及参考这里:http://support.microsoft.com/default.aspx?scid=kb%3Ben-us%3B313134,花了2个小时才搞定这个问题,特此一记。
代码如下(vs2k5上调试通过):
using System.Runtime.InteropServices;
今天写程序时遇到这个问题,找了msdn及参考这里:http://support.microsoft.com/default.aspx?scid=kb%3Ben-us%3B313134,花了2个小时才搞定这个问题,特此一记。
代码如下(vs2k5上调试通过):
using System.Runtime.InteropServices;
class TreeNodeHelper
{
TreeNode treeNode = null;
public TreeNodeHelper(TreeNode tr)
{
treeNode = tr;
}
/// <summary>
/// 返回TreeNode是否有子结点
/// </summary>
public bool HasChildren
{
get
{
return IsTreeNodeHasChildren(treeNode);
}
set
{
MakeTreeNodeHasChildren(treeNode, value);
}
}
public const UInt32 TV_FIRST = 4352;
public const UInt32 TVSIL_NORMAL = 0;
public const UInt32 TVSIL_STATE = 2;
public const UInt32 TVM_SETIMAGELIST = TV_FIRST + 9;
public const UInt32 TVM_GETNEXTITEM = TV_FIRST + 10;
public const UInt32 TVIF_HANDLE = 16;
public const UInt32 TVIF_STATE = 8;
public const UInt32 TVIS_STATEIMAGEMASK = 61440;
public const UInt32 TVM_SETITEM = TV_FIRST + 13;
public const UInt32 TVM_GETITEM = TV_FIRST + 12;
public const UInt32 TVGN_ROOT = 0;
public const int TVIF_CHILDREN = 64;
// Use a sequential structure layout to define TVITEM for the TreeView.
[StructLayout(LayoutKind.Sequential, Pack = 8, CharSet = CharSet.Auto)]
public struct TV_ITEM
{
public uint mask;
public IntPtr hItem;
public uint state;
public uint stateMask;
public IntPtr pszText;
public int cchTextMax;
public int iImage;
public int iSelectedImage;
public int cChildren;
public IntPtr lParam;
}
// Declare two overloaded SendMessage functions. The
// difference is in the last parameter: one is ByVal and the
// other is ByRef.
[DllImport("user32.dll")]
public static extern UInt32 SendMessage(IntPtr hWnd, UInt32 Msg,
UInt32 wParam, UInt32 lParam);
[DllImport("User32", CharSet = CharSet.Auto)]
public static extern IntPtr SendMessage(IntPtr hWnd, UInt32 msg,
UInt32 wParam, ref TV_ITEM lParam);
/// <summary>
/// 指定TreeNode是否有子结点(有子结点则TreeNode会显示+号,没有则不会显示)
/// </summary>
/// <param name="tr"></param>
/// <param name="bHasChildren"></param>
public static void MakeTreeNodeHasChildren(TreeNode tr, bool bHasChildren)
{
TV_ITEM tvItem = new TV_ITEM();
tvItem.mask = TVIF_CHILDREN | TVIF_HANDLE;
tvItem.hItem = tr.Handle;
tvItem.cChildren = bHasChildren ? 1 : 0;
SendMessage(tr.TreeView.Handle, TVM_SETITEM, 0, ref tvItem);
}
/// <summary>
/// 返回树结点是否有子结点
/// </summary>
/// <param name="?"></param>
/// <returns></returns>
public static bool IsTreeNodeHasChildren(TreeNode tr)
{
if (tr.Nodes.Count > 0)
{
return true;
}
TV_ITEM tvItem = new TV_ITEM();
tvItem.mask = TVIF_CHILDREN | TVIF_HANDLE;
tvItem.hItem = tr.Handle;
SendMessage(tr.TreeView.Handle, TVM_GETITEM, 0, ref tvItem);
return tvItem.cChildren == 1;
}
}
{
TreeNode treeNode = null;
public TreeNodeHelper(TreeNode tr)
{
treeNode = tr;
}
/// <summary>
/// 返回TreeNode是否有子结点
/// </summary>
public bool HasChildren
{
get
{
return IsTreeNodeHasChildren(treeNode);
}
set
{
MakeTreeNodeHasChildren(treeNode, value);
}
}
public const UInt32 TV_FIRST = 4352;
public const UInt32 TVSIL_NORMAL = 0;
public const UInt32 TVSIL_STATE = 2;
public const UInt32 TVM_SETIMAGELIST = TV_FIRST + 9;
public const UInt32 TVM_GETNEXTITEM = TV_FIRST + 10;
public const UInt32 TVIF_HANDLE = 16;
public const UInt32 TVIF_STATE = 8;
public const UInt32 TVIS_STATEIMAGEMASK = 61440;
public const UInt32 TVM_SETITEM = TV_FIRST + 13;
public const UInt32 TVM_GETITEM = TV_FIRST + 12;
public const UInt32 TVGN_ROOT = 0;
public const int TVIF_CHILDREN = 64;
// Use a sequential structure layout to define TVITEM for the TreeView.
[StructLayout(LayoutKind.Sequential, Pack = 8, CharSet = CharSet.Auto)]
public struct TV_ITEM
{
public uint mask;
public IntPtr hItem;
public uint state;
public uint stateMask;
public IntPtr pszText;
public int cchTextMax;
public int iImage;
public int iSelectedImage;
public int cChildren;
public IntPtr lParam;
}
// Declare two overloaded SendMessage functions. The
// difference is in the last parameter: one is ByVal and the
// other is ByRef.
[DllImport("user32.dll")]
public static extern UInt32 SendMessage(IntPtr hWnd, UInt32 Msg,
UInt32 wParam, UInt32 lParam);
[DllImport("User32", CharSet = CharSet.Auto)]
public static extern IntPtr SendMessage(IntPtr hWnd, UInt32 msg,
UInt32 wParam, ref TV_ITEM lParam);
/// <summary>
/// 指定TreeNode是否有子结点(有子结点则TreeNode会显示+号,没有则不会显示)
/// </summary>
/// <param name="tr"></param>
/// <param name="bHasChildren"></param>
public static void MakeTreeNodeHasChildren(TreeNode tr, bool bHasChildren)
{
TV_ITEM tvItem = new TV_ITEM();
tvItem.mask = TVIF_CHILDREN | TVIF_HANDLE;
tvItem.hItem = tr.Handle;
tvItem.cChildren = bHasChildren ? 1 : 0;
SendMessage(tr.TreeView.Handle, TVM_SETITEM, 0, ref tvItem);
}
/// <summary>
/// 返回树结点是否有子结点
/// </summary>
/// <param name="?"></param>
/// <returns></returns>
public static bool IsTreeNodeHasChildren(TreeNode tr)
{
if (tr.Nodes.Count > 0)
{
return true;
}
TV_ITEM tvItem = new TV_ITEM();
tvItem.mask = TVIF_CHILDREN | TVIF_HANDLE;
tvItem.hItem = tr.Handle;
SendMessage(tr.TreeView.Handle, TVM_GETITEM, 0, ref tvItem);
return tvItem.cChildren == 1;
}
}