I need to do a custom sort on a TreeView. I have various object types
associated with the TreeNode Tag property. I want to sort objects of
the same type at the top of the list, other objects at the bottom. I
found some scraps of code in various postings that I am trying to get to
work.
I can not seem to get any meaningful data back from the CompareFunc
callback. According to MSDN, The lParam1 and lParam2 parameters
correspond to the lParam member of the TVITEM structure for the two
items being compared. Does this correspond to the TreeNode Text or Tag
property?
Anyway, I am not certain what data types these are but I tried using
Marshal.PtrToStringAuto which returned null strings.
Thanks in advance for any tips or direction,
-Ed
using System.Runtime.InteropServices;
namespace TreeViewSort
{
public class TreeViewEx : TreeView
{
public const int TV_FIRST = 0x1100;
public const int TVM_SORTCHILDRENCB = TV_FIRST + 21;
public delegate int CompareFuncDelegate (IntPtr lParam1,
IntPtr lParam2,
IntPtr lParamSort);
[StructLayout(LayoutKind.Sequential)]
public struct TVSORTCB
{
public IntPtr hParent;
[MarshalAs(UnmanagedType.FunctionPtr)]
public CompareFuncDelegate lpfnCompare;
public IntPtr lParam ;
}
public TreeViewEx()
{
}
private int CompareFunc(IntPtr lParam1,
IntPtr lParam2,
IntPtr lParamSort)
{
// How do I convert lParams into something I can compare?
// Marshal.PtrToStringAuto returns null strings
string str1 = Marshal.PtrToStringAuto(lParam1);
string str2 = Marshal.PtrToStringAuto(lParam2);
return 0;
}
public void Sort()
{
// Build and send the sort message
TVSORTCB sort;
sort.hParent = base.Nodes[0].Handle;
sort.lpfnCompare = new CompareFuncDelegate(this.CompareFunc);
sort.lParam = IntPtr.Zero;
IntPtr ptrTVSORTCB = Marshal.AllocHGlobal(Marshal.SizeOf(sort));
Marshal.StructureToPtr(sort,ptrTVSORTCB,false) ;
Message msg = Message.Create(base.Handle,
TVM_SORTCHILDRENCB,
IntPtr.Zero,
ptrTVSORTCB);
base.WndProc(ref msg);
Marshal.FreeHGlobal(ptrTVSORTCB);
this.Refresh();
}
}
}