Как поменять местами ноды в TreeView?
От: Аноним  
Дата: 02.01.05 17:52
Оценка:
как поменять местами две соседние ноды в TreeView, вместе с их содержимым?
TreeNode node = treeView1.SelectedNode;
TreeNode pnode = treeView1.SelectedNode.PrevNode;
а может надо оперировать TreeNodeCollection?
TreeNodeCollection node = treeView1.SelectedNode.Nodes;
TreeNodeCollection pnode = treeView1.SelectedNode.PrevNode.Nodes;
вобще я плохо представляю как вобще можно оперировать этим элментом управления
Чую,что это просто, но почему-то в моих "толстых" учебниках написано очень кратко
Как поменять местами ноды в TreeView?
От: Аноним  
Дата: 02.01.05 20:57
Оценка:
см. TreeNodeCollection.Remove()/TreeNodeCollection.Insert()


данное сообщение получено с www.gotdotnet.ru
ссылка на оригинальное сообщение
Re: Как поменять местами ноды в TreeView?
От: Mad_Alex Россия  
Дата: 03.01.05 00:48
Оценка:
(теперь я зареганный)
Вобщем у меня задача реализовать перемещение узлов вверх/вниз
я сделал это вот так для кнопки "Вверх"
private void Up_button_Click(object sender, System.EventArgs e)
{
int n=treeView1.SelectedNode.Index;
if(n!=0)//может двигаться выше уже некуда
{
TreeNode node = treeView1.SelectedNode;
if(n!=node.Parent.GetNodeCount(false)-1)//для последнего узла нужно использовать другой метод
{
TreeNode pnode=treeView1.SelectedNode.PrevNode;
node.Remove();
pnode.Remove();
treeView1.SelectedNode.Parent.Nodes.Insert(n-1,pnode);
treeView1.SelectedNode.Parent.Nodes.Insert(n-1,node);
treeView1.SelectedNode=node;
}
else //если узел самый последний
{
TreeNode pnode=treeView1.SelectedNode.PrevNode;
pnode.Remove();
treeView1.SelectedNode.Parent.Nodes.Add(pnode);
}
}
}
всё работает. но неужели нельзя сделать это как-то... по нормальному?
Re[2]: Как поменять местами ноды в TreeView?
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 03.01.05 09:43
Оценка:
Здравствуйте, Mad_Alex, Вы писали:

Просьба выделять код соответствующими тегами.
... << RSDN@Home 1.1.4 beta 3 rev. 272>>
AVK Blog
Re: Как поменять местами ноды в TreeView?
От: Аноним  
Дата: 03.01.05 21:37
Оценка:
>всё работает. но неужели нельзя сделать это как-то... по нормальному?

Без удаления и вставки? Я думаю нельзя.



данное сообщение получено с www.gotdotnet.ru
ссылка на оригинальное сообщение
Re[2]: Как поменять местами ноды в TreeView?
От: Zuka Россия  
Дата: 08.01.05 07:55
Оценка:
Здравствуйте, 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;
            }
}


Это коллекция, а не массив поэтому менять ноды местами не нужно.
Re[3]: Как поменять местами ноды в TreeView?
От: Nikolay_P_I  
Дата: 11.01.05 06:55
Оценка:
Здравствуйте, Zuka, Вы писали:

M_A>>всё работает. но неужели нельзя сделать это как-то... по нормальному?


Z>Можно


Z>
Z>                selected_node.Remove();
Z>


Z>Это коллекция, а не массив поэтому менять ноды местами не нужно.


Я-бы еще обратил внимание на состояние Expand после такого Remove.

По-моему — оно сбросится в false у всех нод внутри убранной.

Так что если хочется сортировку при изменении ноды — придется еще и эту проблему решать.
Re[2]: Как поменять местами ноды в TreeView?
От: greatvict www.insat.ru
Дата: 19.01.05 09:15
Оценка: 6 (1)
Здравствуйте, 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>>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.