Example #1
0
        // Iterates through TreeViewGridNodes in preorder (parent first, then children), this 'flattens' the tree.
        private TreeViewGridNode NextNode(TreeViewGridNode node)
        {
            // After me is my first child (if it exists)

            // In the search, we assume that graph nodes have no children.  This avoids infinite search.
            if (!node.IsGraphNode)
            {
                var callees = callees;
                if (callees != null && callees.Count > 0)
                {
                    return(callees[0]);
                }
            }

            // Otherwise it is my next sibling
            while (node != null)
            {
                var nextSibling = NextSibling(node);
                if (nextSibling != null)
                {
                    return(nextSibling);
                }
                node = node.Caller;
            }
            return(null);
        }
Example #2
0
            /// <summary>
            /// It is assumed that the node oldFlattenedTree[oldIndex] and newFlattenedTree[newIndex] correspond
            /// to one another (have the same path to root)
            /// Copies the expandedness of the node 'oldFlattenedTree[oldIndex]' to the new node at
            /// newFlattenedTree[newIndex], as well as all the state for child node.
            /// </summary>
            internal static void CopyExpandedStateForNode(List <TreeViewGridNode> newFlattenedTree, int newIndex,
                                                          ObservableCollectionEx <TreeViewGridNode> oldFlattenedTree, int oldIndex)
            {
                Debug.Assert(newIndex == newFlattenedTree.Count - 1);
                TreeViewGridNode oldNode = oldFlattenedTree[oldIndex];

                if (oldNode.m_isExpanded)
                {
                    TreeViewGridNode newNode = newFlattenedTree[newIndex];
                    Debug.Assert(newNode.Name == oldNode.Name);
                    newNode.m_isExpanded = true;
                    if (newNode.HasChildren)
                    {
                        var children = newNode.MakeChildren();
                        for (int i = 0; i < children.Count; i++)
                        {
                            var newChild = children[i];
                            newFlattenedTree.Add(newChild);
                            int oldChildIndex = FindChild(oldFlattenedTree, oldNode, oldIndex, newChild.Name);
                            if (oldChildIndex >= 0)
                            {
                                CopyExpandedStateForNode(newFlattenedTree, newFlattenedTree.Count - 1, oldFlattenedTree, oldChildIndex);
                            }
                        }
                    }
                }
            }
Example #3
0
 internal TreeViewGridNode(TreeViewGrid treeView, object data, TreeViewGridNode parent)
 {
     m_treeView   = treeView;
     Data         = data;
     m_isExpanded = !HasChildren;
     m_parent     = parent;
     if (parent != null)
     {
         m_depth = parent.m_depth + 1;
     }
 }
Example #4
0
            /// <summary>
            /// An Unexpanded TreeViewGridNode does not have any children even if the Data (TreeViewGridNode) does
            /// This routine will make the necessary children (it is part of expanding the node).
            /// </summary>
            private List <TreeViewGridNode> MakeChildren()
            {
                Debug.Assert(HasChildren);
                var ret = new List <TreeViewGridNode>();
                TreeViewGridNode lastChild = null;

                foreach (var modelNode in m_treeView.m_controller.Children(Data))
                {
                    lastChild = new TreeViewGridNode(m_treeView, modelNode, this);
                    ret.Add(lastChild);
                }
                lastChild.m_isLastChild = true;
                return(ret);
            }
Example #5
0
        /// <summary>
        /// Find the sampleIndex in the 'Callees' list of the parent for 'node'
        /// </summary>
        /// <param name="node"></param>
        /// <returns></returns>
        private int IndexInParent(TreeViewGridNode node)
        {
            // TODO avoid search
            var callerCallees = DisplayCallees(node.Caller);
            int i             = 0;

            while (i < callerCallees.Count)
            {
                var callee = callerCallees[i];
                if (callee == node)
                {
                    break;
                }
                i++;
            }
            return(i);
        }
Example #6
0
        private TreeViewGridNode NextSibling(TreeViewGridNode node)
        {
            var parent = node.Caller;

            if (parent == null)
            {
                return(null);
            }
            int nextIndex     = IndexInParent(node) + 1;
            var parentCallees = DisplayCallees(parent);

            if (nextIndex >= parentCallees.Count)
            {
                return(null);
            }
            return(parentCallees[nextIndex]);
        }
Example #7
0
        private void Select(TreeViewGridNode item)
        {
            Grid.SelectedCells.Clear();
            Grid.SelectedItem = item;
            if (item == null)
            {
                Debug.Assert(false, "Null item selected:");
                return;
            }
            Grid.ScrollIntoView(item);

            // TODO This stuff feels like a hack.  At some point review.
            var row = (DataGridRow)Grid.ItemContainerGenerator.ContainerFromItem(item);

            if (row != null)
            {
                row.MoveFocus(
                    new System.Windows.Input.TraversalRequest(System.Windows.Input.FocusNavigationDirection.Next));
            }
        }
Example #8
0
        /// <summary>
        /// Typically the GUI instantiates the TreeViewGrid as part of some XAML.   However to do its job that
        /// object needs to know what data it is operating on.  This is what 'SetController' does.   By defining
        /// an object implementing ITreeViewController and passing it to this method, you populate the TreeViewGrid
        /// with data.
        /// </summary>
        public void SetController(ITreeViewController controller)
        {
            m_controller = controller;

            // Set up the columns
            for (int i = 0; i < m_controller.ColumnNames.Count; i++)
            {
                var columnName = m_controller.ColumnNames[i];
                var columnIdx  = i + 1;     // Skip the name column
                if (columnIdx < Grid.Columns.Count)
                {
                    var column = Grid.Columns[columnIdx];
                    column.Header     = columnName;
                    column.Visibility = System.Windows.Visibility.Visible;
                }
            }

            List <TreeViewGridNode> newFlattenedTree = new List <TreeViewGridNode>();

            newFlattenedTree.Add(new TreeViewGridNode(this, controller.Root, null));

            // Copy over the nodes to the new flattened tree (as best we can)
            if (m_flattenedTree.Count > 0 && m_flattenedTree[0].Name == controller.Name(controller.Root))
            {
                TreeViewGridNode.CopyExpandedStateForNode(newFlattenedTree, 0, m_flattenedTree, 0);
            }

            // Destroy old nodes (to save memory because GUI keeps references to them)
            foreach (var node in m_flattenedTree)
            {
                node.Dispose();
            }

            // Update the whole tree with the new tree.
            m_flattenedTree.ReplaceRange(0, m_flattenedTree.Count, newFlattenedTree);
            Validate();

            // Expand the root element
            m_flattenedTree[0].IsExpanded = true;
        }
Example #9
0
        /// <summary>
        /// Given a TreeViewGridNode, find a TreeViewGridNode for it (insuring that it is displayed)
        /// </summary>
        private TreeViewGridNode InsureVisible(object treeNode)
        {
            if (treeNode == null)
            {
                return(m_flattenedTree[0]);
            }

            throw new NotImplementedException();
            TreeViewGridNode caller = InsureVisible(treeNode.Caller);

            if (caller == null)         // should never happen, but we can fall back to giving up.
            {
                return(null);
            }
            caller.IsExpanded = true;
            caller.ValidateTree();

            int callerPos = caller.MyIndex + 1;

            while (callerPos < m_flattenedTree.Count)
            {
                var child = m_flattenedTree[callerPos];
                if (child.m_depth <= caller.m_depth)
                {
                    break;
                }

                if (child.Data == treeNode)
                {
                    return(child);
                }

                callerPos++;
            }
            Debug.Assert(false, "Should have found call node");
            return(null);
        }
Example #10
0
            /// <summary>
            /// Given a node == flattenedTree[sampleIndex] find the sampleIndex in flattenedTree of a child with Name == 'name'
            /// </summary>
            private static int FindChild(ObservableCollectionEx <TreeViewGridNode> flattenedTree, TreeViewGridNode node, int index, string name)
            {
                Debug.Assert(flattenedTree[index] == node);
                int childDepth = node.m_depth + 1;
                int childIndex = index;

                for (; ;)
                {
                    childIndex++;
                    if (childIndex >= flattenedTree.Count)
                    {
                        break;
                    }
                    var child = flattenedTree[childIndex];
                    if (child.m_depth < childDepth)
                    {
                        break;
                    }
                    if (child.m_depth == childDepth && child.Name == name)
                    {
                        return(childIndex);
                    }
                }
                return(-1);
            }