Index: Core/Common/src/Core.Common.Controls.TreeView/TreeViewControl.cs =================================================================== diff -u -ra5294651797be8410ae92057a92f38767a37d53f -r67b333d96775b6b14ca2f64fa10f929f9448d143 --- Core/Common/src/Core.Common.Controls.TreeView/TreeViewControl.cs (.../TreeViewControl.cs) (revision a5294651797be8410ae92057a92f38767a37d53f) +++ Core/Common/src/Core.Common.Controls.TreeView/TreeViewControl.cs (.../TreeViewControl.cs) (revision 67b333d96775b6b14ca2f64fa10f929f9448d143) @@ -82,13 +82,13 @@ private const int checkedCheckBoxStateImageIndex = 1; private const int updateTimerInterval = 10; - private object data; - private Timer updateTimer; - private readonly DragDropHandler dragDropHandler = new DragDropHandler(); private readonly Dictionary tagTypeTreeNodeInfoLookup = new Dictionary(); private readonly Dictionary treeNodeObserverLookup = new Dictionary(); + private object data; + private Timer updateTimer; + public event EventHandler DataDoubleClick; public event EventHandler SelectedDataChanged; public event EventHandler> DataDeleted; // TODO; Way to explicit! @@ -588,33 +588,64 @@ private void RefreshChildNodes(TreeNode treeNode, TreeNodeInfo treeNodeInfo) { - IEnumerable currentTreeNodes = treeNode.Nodes.Cast().ToList(); - Dictionary currentTreeNodesPerTag = currentTreeNodes.ToDictionary(ctn => ctn.Tag, ctn => ctn); + IList newlyAddedTreeNodes = new List(); object[] newChildNodeObjects = treeNodeInfo.ChildNodeObjects != null ? treeNodeInfo.ChildNodeObjects(treeNode.Tag) : new object[0]; - // Obtain a collection of refreshed nodes, recycling any existing nodes - List refreshedTreeNodes = newChildNodeObjects.Select( - cno => currentTreeNodesPerTag.ContainsKey(cno) - ? currentTreeNodesPerTag[cno] - : CreateTreeNode(treeNode, cno)).ToList(); - - // Remove any outdated nodes - foreach (TreeNode removedNode in currentTreeNodes.Except(refreshedTreeNodes)) + for (var i = 0; i < newChildNodeObjects.Length; i++) { - RemoveTreeNodeFromLookupRecursively(removedNode); - } + // Remove any outdated node at the current position + if (treeNode.Nodes.Count > i && !newChildNodeObjects.Contains(treeNode.Nodes[i].Tag)) + { + TreeNode nodeToRemove = treeNode.Nodes[i]; - treeNode.Nodes.Clear(); + treeNode.Nodes.Remove(nodeToRemove); + RemoveTreeNodeFromLookupRecursively(nodeToRemove); + } - foreach (TreeNode node in refreshedTreeNodes) + object newChildNodeObject = newChildNodeObjects[i]; + + // Continue on correct node + if (treeNode.Nodes.Count > i && newChildNodeObject.Equals(treeNode.Nodes[i].Tag)) + { + continue; + } + + IList currentTreeNodes = treeNode.Nodes.Cast().ToList(); + Dictionary currentTagIndexLookup = currentTreeNodes.Select((node, index) => new + { + node, + index + }) + .ToDictionary(x => x.node.Tag, x => x.index); + + if (currentTagIndexLookup.ContainsKey(newChildNodeObject)) + { + // Move existing node + int currentTreeNodeIndex = currentTagIndexLookup[newChildNodeObject]; + TreeNode existingTreeNode = currentTreeNodes[currentTreeNodeIndex]; + treeNode.Nodes.RemoveAt(currentTreeNodeIndex); + treeNode.Nodes.Insert(i, existingTreeNode); + } + else + { + // Insert new node + TreeNode newTreeNode = CreateTreeNode(treeNode, newChildNodeObject); + treeNode.Nodes.Insert(i, newTreeNode); + newlyAddedTreeNodes.Add(newTreeNode); + } + } + + // Remove any outdated nodes at the end + IEnumerable outdatedTreeNodes = treeNode.Nodes.Cast().Skip(newChildNodeObjects.Length); + foreach (TreeNode outdatedNode in outdatedTreeNodes) { - treeNode.Nodes.Add(node); + treeNode.Nodes.Remove(outdatedNode); } // If relevant, set selection to the last of the added nodes - SelectLastNewNode(refreshedTreeNodes); + SelectLastNewNode(newlyAddedTreeNodes); } private void SelectLastNewNode(IEnumerable newTreeNodes)