示例#1
0
        /// <summary>
        /// Reparents the given elements
        /// </summary>
        /// <param name="parentElement"></param>
        /// <param name="insertionIndex"></param>
        /// <param name="elements"></param>
        public void MoveElements(TreeElement parentElement, int insertionIndex, params TreeElement[] elements)
        {
            if (insertionIndex < 0)
            {
                throw new ArgumentException("Invalid input: insertionIndex is -1, client needs to decide what index elements should be reparented at");
            }

            // Invalid reparenting input
            if (parentElement == null)
            {
                return;
            }

            // We are moving items so we adjust the insertion index to accomodate that any items above the insertion index is removed before inserting
            if (insertionIndex > 0)
            {
                insertionIndex -= parentElement.children.GetRange(0, insertionIndex).Count(elements.Contains);
            }

            // Remove draggedItems from their parents
            foreach (var draggedItem in elements)
            {
                draggedItem.parent.children.Remove(draggedItem); // remove from old parent
                draggedItem.parent = parentElement;              // set new parent
            }

            if (parentElement.children == null)
            {
                parentElement.children = new List <TreeElement>();
            }

            // Insert dragged items under new parent
            parentElement.children.InsertRange(insertionIndex, elements);

            TreeElement.UpdateDepthValues(root);
            TreeElement.TreeToList(this.root, this.data);

            OnChanged();
        }
示例#2
0
        /// <summary>
        /// Removes the given elements
        /// </summary>
        /// <param name="elements"></param>
        public void RemoveElements(IList <T> elements)
        {
            foreach (var element in elements)
            {
                if (element == this.root)
                {
                    throw new ArgumentException("It is not allowed to remove the root element");
                }
            }

            var commonAncestors = TreeElement.FindCommonAncestorsWithinList(elements);

            foreach (var element in commonAncestors)
            {
                element.parent.children.Remove(element);
                element.parent = null;
            }

            TreeElement.TreeToList(this.root, this.data);

            OnChanged();
        }
示例#3
0
        /// <summary>
        /// Reparents the given elements
        /// </summary>
        /// <param name="parent"></param>
        /// <param name="insertionIndex"></param>
        /// <param name="children"></param>
        public static void Parent(TreeElement parent, params TreeElement[] children)
        {
            // Invalid reparenting input
            if (parent == null)
            {
                return;
            }

            // Remove draggedItems from their parents
            foreach (var child in children)
            {
                Parent(parent, child);
                UpdateDepthValues(child);
            }

            if (parent.children == null)
            {
                parent.children = new List <TreeElement>();
            }

            // Insert dragged items under new parent
            parent.children.AddRange(children);
        }
示例#4
0
        //------------------------------------------------------------------------/
        // Methods: Private
        //------------------------------------------------------------------------/
        private IList <int> GetParentsBelowStackBased(TreeElement searchFromThis)
        {
            Stack <TreeElement> stack = new Stack <TreeElement>();

            stack.Push(searchFromThis);

            var parentsBelow = new List <int>();

            while (stack.Count > 0)
            {
                TreeElement current = stack.Pop();
                if (current.hasChildren)
                {
                    parentsBelow.Add(current.id);
                    foreach (var T in current.children)
                    {
                        stack.Push(T);
                    }
                }
            }

            return(parentsBelow);
        }
示例#5
0
        public static void TestTreeModelCanRemoveElements()
        {
            var root = new TreeElement {
                name = "Root", depth = -1
            };
            var listOfElements = new List <TreeElement>();

            listOfElements.Add(root);

            var model = new TreeModel <TreeElement>(listOfElements);

            model.AddElement(new TreeElement {
                name = "Element"
            }, root, 0);
            model.AddElement(new TreeElement {
                name = "Element " + root.children.Count
            }, root, 0);
            model.AddElement(new TreeElement {
                name = "Element " + root.children.Count
            }, root, 0);
            model.AddElement(new TreeElement {
                name = "Sub Element"
            }, root.children[1], 0);

            model.RemoveElements(new[] { root.children[1].children[0], root.children[1] });

            // Assert order is correct
            string[] namesInCorrectOrder = { "Root", "Element 2", "Element" };
            Assert.AreEqual(namesInCorrectOrder.Length, listOfElements.Count, "Result count does not match");
            for (int i = 0; i < namesInCorrectOrder.Length; ++i)
            {
                Assert.AreEqual(namesInCorrectOrder[i], listOfElements[i].name);
            }

            // Assert depths are valid
            TreeElement.Assert(listOfElements);
        }
示例#6
0
        /// <summary>
        /// Adds an element onto the tree
        /// </summary>
        /// <param name="element"></param>
        /// <param name="parent"></param>
        /// <param name="insertPosition"></param>
        public void AddElement(T element, TreeElement parent, int insertPosition)
        {
            if (element == null)
            {
                throw new ArgumentNullException("element", "element is null");
            }
            if (parent == null)
            {
                throw new ArgumentNullException("parent", "parent is null");
            }

            if (parent.children == null)
            {
                parent.children = new List <TreeElement>();
            }

            parent.children.Insert(insertPosition, element);
            element.parent = parent;

            TreeElement.UpdateDepthValues(parent);
            TreeElement.TreeToList(this.root, this.data);

            OnChanged();
        }
示例#7
0
        /// <summary>
        /// Returns the root of the tree parsed from the list (always the first element)
        /// Note: The first element is requried to have a depth value of -1, with the rest
        /// of the elements at a depth >= 0
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="list"></param>
        /// <returns></returns>
        public static T ListToTree <T>(IList <T> list) where T : TreeElement
        {
            // Validate input
            TreeElement.Assert(list);

            // Clear old state
            foreach (var element in list)
            {
                element.parent   = null;
                element.children = null;
            }

            // Set child and parent references using depth info
            for (int parentIndex = 0; parentIndex < list.Count; parentIndex++)
            {
                T parent = list[parentIndex];

                // Been visited before
                bool alreadyHasValidChildren = parent.children != null;
                if (alreadyHasValidChildren)
                {
                    continue;
                }

                // Count children based depth value, lookign at children until its
                // the same depth of this element
                int parentDepth = parent.depth;
                int childCount  = 0;
                for (int i = parentIndex + 1; i < list.Count; i++)
                {
                    int depth = list[i].depth;
                    if (depth == parentDepth + 1)
                    {
                        childCount++;
                    }
                    else if (depth <= parentDepth)
                    {
                        break;
                    }
                }

                // Fill the child array for this element
                List <TreeElement> children = null;
                if (childCount != 0)
                {
                    children   = new List <TreeElement>(childCount);
                    childCount = 0;

                    for (int i = parentIndex + 1; i < list.Count; i++)
                    {
                        int depth = list[i].depth;
                        if (depth == parentDepth + 1)
                        {
                            list[i].parent = parent;
                            children.Add(list[i]);
                            childCount++;
                        }

                        if (depth <= parentDepth)
                        {
                            break;
                        }
                    }
                }

                parent.children = children;
            }

            // Now return the root
            return(list[0]);
        }
示例#8
0
 private void Parse()
 {
     _root = TreeElement.ListToTree(this.elements);
 }
示例#9
0
 /// <summary>
 /// Reparents the given elements
 /// </summary>
 /// <param name="parentElement"></param>
 /// <param name="insertionIndex"></param>
 /// <param name="elements"></param>
 public void Reparent(TreeElement parentElement, List <TreeElement> elements)
 {
     TreeElement.Parent(parentElement, elements.ToArray());
 }
示例#10
0
 /// <summary>
 /// Reparents the given elements
 /// </summary>
 /// <param name="parentElement"></param>
 /// <param name="insertionIndex"></param>
 /// <param name="elements"></param>
 public void Reparent(TreeElement parentElement, params TreeElement[] elements)
 {
     TreeElement.Parent(parentElement, elements);
 }
示例#11
0
        public Exception Validate()
        {
            Exception exception = TreeElement.Validate(this.elements);

            return(exception);
        }
示例#12
0
 //------------------------------------------------------------------------/
 // Methods: Public
 //------------------------------------------------------------------------/
 public void Assert()
 {
     TreeElement.Assert(this.elements);
 }
示例#13
0
 /// <summary>
 /// Reparents the given elements
 /// </summary>
 /// <param name="parentElement"></param>
 /// <param name="insertionIndex"></param>
 /// <param name="elements"></param>
 public void MoveElements(TreeElement parentElement, int insertionIndex, List <TreeElement> elements)
 {
     MoveElements(parentElement, insertionIndex, elements.ToArray());
 }