TreeView, перемещение узла в избранное  новое    подписка   модер. 
От: manenkov 
Дата: 24.03.08 06:45
День добрый.

Делаю перемещение узла в дереве TreeView (нужно взять выбранный нод и сдвинуть его вверх, т.е. поменять местами с нодом что над ним):


private void bUp_Click(object sender, EventArgs e)
        {
            Console.Out.WriteLine("List of nodes:");
            // СПИСОК_1
            foreach (TreeNode nd in treeMain.Nodes)
            {
                Console.Out.WriteLine(nd.Text);
            }
 
            TreeNode node = treeMain.SelectedNode.PrevNode;
            TreeNode nodeS = treeMain.SelectedNode;
            int n = treeMain.SelectedNode.Index;
            if (treeMain.SelectedNode.Parent == null)
            {
                // ОСНОВНОЙ БЛОК
                if (n > 0)
                {
                    treeMain.Nodes[n] = node;
                    treeMain.Nodes[n - 1] = nodeS; 
                    treeMain.Invalidate();
                    treeMain.Refresh(); 
                    Console.Out.WriteLine("List of nodes:");
                    // СПИСОК_2
                    foreach (TreeNode nd in treeMain.Nodes)
                    {
                        Console.Out.WriteLine(nd.Text);
                    }
                }
            }
            else
            {
                // ЭТОТ БЛОК НЕЗНАЧИМ, ОТЛАДКА ИДЕТ НА ОСНОВНОМ БЛОКЕ
                if (n > 0)
                {
                    treeMain.SelectedNode.Parent.Nodes[n] = node;
                    treeMain.SelectedNode.Parent.Nodes[n - 1] = nodeS;                     
                } 
            }                         
        }


Работаю с деревом, где есть узлы только верхнего уровня с именами q, w, e, r, t, y, u.

Получается такая картина. Блок СПИСОК_1 выводит список q, w, e, r, t, y, u. Выбираю узел 'e' (неважно что именно 'e', просто для примера). двигаю его вверх (т.е. для него вызывается этот обработчик). СПИСОК_2 выводит правильный список: q, e, w, r, t, y, u. Но дерево отображается вот так: q, e, w, w, e, r, t, y, u.

То есть модель дерева меняется нормально, но почему-то отрисовывается что-то не то.

В чем может быть дело?

Спасибо.


24.03.08 13:28: Перенесено модератором из '.NET' — AndrewVK
Re: TreeView, перемещение узла в избранное  новое    модер. 
От: Shurik_ 
Дата: 24.03.08 10:12
Удалить узел, который нужно переместить и вставить в нужную позицию.
TreeNode n = treeView1.Nodes[3];
treeView.Nodes.Remove(n);
treeView.Nodes.Insert(2, n);
Re[2]: TreeView, перемещение узла в избранное  новое    модер. 
От: manenkov 
Дата: 25.03.08 06:36
Здравствуйте, Shurik_, Вы писали:

S_>Удалить узел, который нужно переместить и вставить в нужную позицию.

S_>
S_>TreeNode n = treeView1.Nodes[3];
S_>treeView.Nodes.Remove(n);
S_>treeView.Nodes.Insert(2, n);
S_>

Да, это я уже сделал, хотелось бы понять в чем проблема с первым вариантом кода.
Re[3]: TreeView, перемещение узла в избранное  новое    модер. 
От: Константин Б. 
Дата: 25.03.08 16:18
Оценка:2 (1)
Здравствуйте, manenkov, Вы писали:

M>Да, это я уже сделал, хотелось бы понять в чем проблема с первым вариантом кода.


treeMain.Nodes[n] = node;
treeMain.Nodes[n - 1] = nodeS;


TreeNodeCollection.set_Item устроен очень любопытным образом:

public virtual void set_Item(int index, TreeNode value)
{
    if ((index < 0) || (index >= this.owner.childCount))
    {
        throw new ArgumentOutOfRangeException("index", SR.GetString("InvalidArgument", new object[] { "index", index.ToString(CultureInfo.CurrentCulture) }));
    }
    value.parent = this.owner;
    value.index = index;
    this.owner.children[index] = value;
    value.Realize(false); // Внутри посылается TVM_INSERTITEM контролу
}


Как видим не делается никаких попыток удалить старый узел расположенный по индексу. Поэтому при каждом вызове этого метода появляется лишний узел в контроле, но не в массиве.