см. TreeNodeCollection.Remove()/TreeNodeCollection.Insert()
данное сообщение получено с www.gotdotnet.ru
ссылка на оригинальное сообщение
Здравствуйте, Mad_Alex, Вы писали:
Просьба выделять код соответствующими тегами.
... << RSDN@Home 1.1.4 beta 3 rev. 272>>
>всё работает. но неужели нельзя сделать это как-то... по нормальному?
Без удаления и вставки? Я думаю нельзя.
данное сообщение получено с www.gotdotnet.ru
ссылка на оригинальное сообщение
Здравствуйте, Mad_Alex, Вы писали:
M_A>всё работает. но неужели нельзя сделать это как-то... по нормальному?
Можно
{
TreeNode parent = treeView1.SelectedNode.Parent;
TreeNode selected_node = treeView1.SelectedNode;
TreeNode prev_node = selected_node.PrevNode;
if (prev_node != null)
{
selected_node.Remove();
parent.Nodes.Insert(prev_node.Index, selected_node);
treeView1.SelectedNode = selected_node;
}
}
Это коллекция, а не массив поэтому менять ноды местами не нужно.
Здравствуйте, Zuka, Вы писали:
M_A>>всё работает. но неужели нельзя сделать это как-то... по нормальному?
Z>Можно
Z>Z> selected_node.Remove();
Z>
Z>Это коллекция, а не массив поэтому менять ноды местами не нужно.
Я-бы еще обратил внимание на состояние Expand после такого Remove.
По-моему — оно сбросится в false у всех нод внутри убранной.
Так что если хочется сортировку при изменении ноды — придется еще и эту проблему решать.
Здравствуйте, SergeyP, Вы писали:
SP>Без удаления и вставки? Я думаю нельзя.
Можно использовать встроенную сортировку, только придется обращаться к функциям Win API —
public class TreeViewSort
{
TreeView _treeView;
ArrayList _nodes;
CompareNodes _proc;
public delegate int CompareNodes(TreeNode node1, TreeNode node2);
public TreeViewSort(TreeView treeView, CompareNodes proc)
{
_treeView = treeView;
_proc = proc;
}
public void SortChildren(TreeNode parentNode)
{
_nodes = new ArrayList();
int index = 0;
foreach (TreeNode childNode in parentNode.Nodes)
{
_nodes.Add(childNode);
TVITEM item = new TVITEM();
item.mask = TVIF_PARAM;
item.hItem = childNode.Handle;
item.lParam = index++;
item.cChildren = 0;
item.cchTextMax = 0;
item.iImage = item.iSelectedImage = 0;
item.state = item.stateMask = 0;
item.pszText = IntPtr.Zero;
IntPtr ptrTVITEM = Marshal.AllocHGlobal(Marshal.SizeOf(item));
Marshal.StructureToPtr(item, ptrTVITEM, false);
SendMessage(_treeView.Handle, TVM_SETITEM, 0, ptrTVITEM);
Marshal.FreeHGlobal(ptrTVITEM);
}
GCHandle handleThis = GCHandle.Alloc(this);
TVSORTCB sort = new TVSORTCB();
sort.hParent = parentNode.Handle;
sort.lpfnCompare = new CompareNodesImplDelegate(CompareNodesImpl);
sort.lParam = (IntPtr)handleThis;
IntPtr ptrTVSORTCB = Marshal.AllocHGlobal(Marshal.SizeOf(sort));
Marshal.StructureToPtr(sort, ptrTVSORTCB, false);
SendMessage(_treeView.Handle, TVM_SORTCHILDRENCB, 0, ptrTVSORTCB);
handleThis.Free();
Marshal.FreeHGlobal(ptrTVSORTCB);
}
const int TV_FIRST = 0x1100;
const int TVM_SORTCHILDRENCB = TV_FIRST + 21;
const int TVM_SETITEM = 4415;
const int TVIF_PARAM = 0x0004;
[StructLayout(LayoutKind.Sequential)]
struct TVSORTCB
{
public IntPtr hParent;
public CompareNodesImplDelegate lpfnCompare;
public IntPtr lParam;
}
[DllImportAttribute("user32.dll", CharSet=CharSet.Auto)]
static extern IntPtr SendMessage(IntPtr hWnd, int msg, int wParam, IntPtr lParam);
[StructLayout(LayoutKind.Sequential)]
struct TVITEM
{
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 int lParam;
}
delegate int CompareNodesImplDelegate(
int lParam1, int lParam2, IntPtr lParamSort);
static int CompareNodesImpl(int lParam1, int lParam2, IntPtr lParamSort)
{
TreeViewSort host = (TreeViewSort)((GCHandle)lParamSort).Target;
//Some bug. Проявляется иногда при удалении единственного контрола
if (lParam1 >= host._nodes.Count)
return 1; //Move lParam1 to the end
if (lParam2 >= host._nodes.Count)
return -1; //Move lParam2 to the end
return host._proc((TreeNode)host._nodes[lParam1], (TreeNode)host._nodes[lParam2]);
}
}
Вызов SortChildren сортирует элементы на одном уровне.
У меня данная процедура вызывается весьма часто и какого-нибудь неудобства замечено не было.
А при Remove/Insert была проблема, если элементы сами являлись поддеревьями.
... << RSDN@Home 1.1.4 beta 3 rev. 185>>