Что самый точный путь состоит в том, чтобы переместить узел вверх и вниз в treeview. Я получил контекстное меню на каждом узле, и выбранный узел должен быть перемещен со всеми его подузлами.
Я использую.Net 3.5 WinForms C#
Вы можете использовать следующие расширения:
public static class Extensions
{
public static void MoveUp(this TreeNode node)
{
TreeNode parent = node.Parent;
TreeView view = node.TreeView;
if (parent != null)
{
int index = parent.Nodes.IndexOf(node);
if (index > 0)
{
parent.Nodes.RemoveAt(index);
parent.Nodes.Insert(index - 1, node);
}
}
else if (node.TreeView.Nodes.Contains(node)) //root node
{
int index = view.Nodes.IndexOf(node);
if (index > 0)
{
view.Nodes.RemoveAt(index);
view.Nodes.Insert(index - 1, node);
}
}
}
public static void MoveDown(this TreeNode node)
{
TreeNode parent = node.Parent;
TreeView view = node.TreeView;
if (parent != null)
{
int index = parent.Nodes.IndexOf(node);
if (index < parent.Nodes.Count -1)
{
parent.Nodes.RemoveAt(index);
parent.Nodes.Insert(index + 1, node);
}
}
else if (view != null && view.Nodes.Contains(node)) //root node
{
int index = view.Nodes.IndexOf(node);
if (index < view.Nodes.Count - 1)
{
view.Nodes.RemoveAt(index);
view.Nodes.Insert(index + 1, node);
}
}
}
}
Дочерние узлы будут следовать за своими родителями.
РЕДАКТИРОВАТЬ: Добавлен случай, когда перемещаемый узел является корнем в TreeView.
Хотя я считаю, что написание этого кода - пустая трата времени, учитывая отсутствие ответа на комментарии со стороны OP, по крайней мере, я могу показать, как пример кода Le-Savard может быть исправлен таким образом, что множественные щелчки вверх или вниз в контекстном меню ... при условии, что контекстное меню не закрывается автоматически каждый раз, и пользователь вынужден выбирать один и тот же узел снова и снова снова ... будет делать правильные вещи с первоначально выбранным узлом и не создавать нежелательных побочных эффектов:
public static class Extensions
{
public static void MoveUp(this TreeNode node)
{
TreeNode parent = node.Parent;
if (parent != null)
{
int index = parent.Nodes.IndexOf(node);
if (index > 0)
{
parent.Nodes.RemoveAt(index);
parent.Nodes.Insert(index - 1, node);
// bw : add this line to restore the originally selected node as selected
node.TreeView.SelectedNode = node;
}
}
}
public static void MoveDown(this TreeNode node)
{
TreeNode parent = node.Parent;
if (parent != null)
{
int index = parent.Nodes.IndexOf(node);
if (index < parent.Nodes.Count - 1)
{
parent.Nodes.RemoveAt(index);
parent.Nodes.Insert(index + 1, node);
// bw : add this line to restore the originally selected node as selected
node.TreeView.SelectedNode = node;
}
}
}
}
Конечно, это исправление по-прежнему не касается того факта, что в коде примера нельзя переместить несколько корневых узлов (поскольку они «лишены родителей»): это легко поправимо.
Это также не касается более интересного случая, когда перемещение верхнего дочернего узла вверх означает, что вы делаете некоторую интерпретацию того, куда должен идти этот «продвинутый» дочерний код: точно такой же «стратегический выбор» задействован там, где вы «спускаетесь вниз». последний дочерний узел родительского узла, и поэтому от него требуется решить, куда он должен идти. В коде Dynami Le-Savard: эти случаи просто игнорируются.
Тем не менее, это выбор проекта , чтобы ограничить перемещение дочернего узла только в пределах их родительских узлов Коллекция узлов: выбор дизайна, который может идеально подходить для одного решения.
Точно так же выбор дизайна заставляет пользователя выбрать узел и щелкнуть контекстным щелчком, чтобы открыть контекстное меню, которое позволяет выбирать перемещение вверх или вниз каждый раз, когда они захотят. чтобы переместить его : это не вариант дизайна, который я бы сделал: я бы использовал перетаскивание здесь или кнопки, которые позволяют многократно быстро перемещать любой выбранный узел в любом месте дерева.
Кстати, мне нравится использование здесь расширений Dynami Le-Savard.