Esempio n. 1
0
        /// <summary>
        /// Updates the tree if items were removed from an observed
        /// child collection. This might cause rendered tree nodes
        /// to be removed. In case lazy loading is enabled, the update
        /// of the UI may be as subtle as to remove an expander from
        /// a collapsed node if the represented item's childs were
        /// removed.
        /// </summary>
        /// <param name="observed">The observed collection.</param>
        /// <param name="e">The event arguments that provide the
        /// removed items.</param>
        private void HandleRemovedChildItems(ICollection <T> observed, NotifyCollectionChangedEventArgs e)
        {
            IList childs = e.OldItems;

            if (childs.Count == 0)
            {
                return;
            }

            //get the node of the parent item that contains the evented childs
            TreeViewItem parentNode = GetParentNode((T)childs[0], observed);

            if (parentNode == null)
            {
                return;
            }

            foreach (T childItem in childs)
            {
                string itemKey = tree.GetItemKey(childItem);

                //check if we have a corresponding open node
                //-> not necessarily the case if we're doing lazy loading
                TreeViewItem childNode;
                childNode = tree.TryFindItemNode(parentNode.Items, itemKey, false);
                if (childNode != null)
                {
                    //unregister listeners
                    UnregisterListeners(childNode);
                    //remove node from UI
                    parentNode.Items.Remove(childNode);
                }
            }

            //in case of lazy loading, the tree might contain a dummy node
            //(has not been expanded). However, it might be that it's now
            //completely empty...
            if (observed.Count == 0)
            {
                TreeUtil.ClearDummyChildNode(parentNode);
                parentNode.IsExpanded = false;
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Updates the tree with newly added items.
        /// </summary>
        /// <param name="observed">The observed collection.</param>
        /// <param name="e">Collection event args.</param>
        public void HandleNewChildItems(ICollection <T> observed, NotifyCollectionChangedEventArgs e)
        {
            IList childs = e.NewItems;

            if (childs.Count == 0)
            {
                return;
            }

            //get the node of the parent item that contains the evented childs
            TreeViewItem parentNode = GetParentNode((T)childs[0], observed);

            if (parentNode == null)
            {
                return;
            }


            //if the node is expanded or does not load lazily, or
            //already contains valid items, create nodes
            if (parentNode.IsExpanded || !tree.IsLazyLoading || !TreeUtil.ContainsDummyNode(parentNode))
            {
                foreach (T child in childs)
                {
                    tree.CreateItemNode(child, parentNode.Items, null);
                }

                //refresh the node in order to apply styling (or any other
                //features that will be incorporated)
                parentNode.Items.Refresh();
            }
            else if (parentNode.Items.Count == 0)
            {
                //if the tree is in lazy loading mode and the item did
                //not contain any childs before, we have to add a dummy
                //node to render a expander
                parentNode.Items.Add(new TreeViewItem());
            }
        }
        /// <summary>
        /// Handles lazy creation of child nodes if a node is being expanded
        /// the first time.
        /// </summary>
        protected virtual void OnNodeExpanded(TreeViewItem treeNode)
        {
            //the node does not represent one of our bound items
            //(custom root or some injected stuff)
            T item = treeNode.Header as T;

            if (item == null)
            {
                return;
            }

            //update the layout
            string itemKey = GetItemKey(item);

            currentLayout.ExpandedNodeIds.Add(itemKey);

            //the tree has already been created - there is nothing more to do here
            if (!IsLazyLoading)
            {
                //the tree has already been created - there is nothing more to do here
                //however, if the node does not contain anything, don't show as expanded
                if (treeNode.Items.Count == 0)
                {
                    treeNode.IsExpanded = false;
                    currentLayout.ExpandedNodeIds.Remove(itemKey);
                }

                return;
            }

            //if we have a dummy node, remove it
            TreeUtil.ClearDummyChildNode(treeNode);

            //get the child items
            ICollection <T> childItems = GetChildItems(item);

            if (treeNode.Items.Count == 0)
            {
                foreach (T childItem in childItems)
                {
                    //create child items with the current layout
                    //-> this also re-expands subitems that were
                    //expanded, but discarded with their ancestor
                    CreateItemNode(childItem, treeNode.Items, currentLayout);
                }

                //refresh to apply sorting
                if (treeNode.Items.NeedsRefresh)
                {
                    treeNode.Items.Refresh();
                }
            }

            if (treeNode.Items.Count == 0)
            {
                //collapse again if there was no data at all
                //unlikely, but the bound item's childs might have changed
                treeNode.IsExpanded = false;
                currentLayout.ExpandedNodeIds.Remove(itemKey);
            }
        }