Beispiel #1
0
        internal override int FindInsertionIndex(ChangeNotificationTracker tracker)
        {
            int insertionIndex = 0;

            if (tracker != null && (tracker.ChildViewModels == null || tracker.ChildViewModels.Count < 1))
            {
                foreach (ModelProperty property in this.Value.Properties)
                {
                    if (property != tracker.ParentProperty)
                    {
                        // assume this would increament
                        ChangeNotificationTracker propertyTracker = this.GetTracker(property, false);
                        if (propertyTracker != null)
                        {
                            insertionIndex = base.FindInsertionIndex(propertyTracker);
                        }
                    }
                    else
                    {
                        // we've reach the property and hence the last of the previous property
                        break;
                    }
                }
            }
            else
            {
                insertionIndex = base.FindInsertionIndex(tracker);
            }

            return(insertionIndex);
        }
Beispiel #2
0
        internal override void UpdateChildren(ChangeNotificationTracker tracker, EventArgs e)
        {
            if (this.PerfEventProvider != null)
            {
                this.PerfEventProvider.DesignerTreeViewUpdateStart();
            }

            // Update VisualValue when promotedProperty's got changed.
            if (this.promotedProperty != null && this.promotedProperty == tracker.ParentProperty)
            {
                this.VisualValue = this.promotedProperty.Value;
            }

            if (this.Children.Count == 1 && this.Children[0] == DummyNode)
            {
                // If the node never expanded before, LoadChildren instead of UpdateChildren.
                // Otherwise, when expanding node, the LoadChildren method won't invoke
                // Then other tracking properties cannot be setup correctly.
                this.InternalChildren.Remove(DummyNode);
                this.LoadChildren();
            }
            else
            {
                // If requireUpdateChildren = false, the related TreeViewItemModelPropertyViewModel take care of updating child nodes.
                bool requireUpdateChildren = true;
                if (e is PropertyChangedEventArgs && this.IsModelPropertyNodeExisted(tracker.ParentProperty))
                {
                    ModelProperty modelProperty = tracker.ParentProperty;
                    if (modelProperty.Value != null)
                    {
                        string changedPropertyName       = ((PropertyChangedEventArgs)e).PropertyName;
                        bool   isPromotedPropertyChanged = TreeViewItemViewModel.IsPromotedProperty(modelProperty.Value, changedPropertyName);
                        if (isPromotedPropertyChanged)
                        {
                            if (modelProperty.Value.Properties[changedPropertyName].Value != null)
                            {
                                requireUpdateChildren = false;
                            }
                        }
                        else
                        {
                            requireUpdateChildren = false;
                        }
                    }
                }

                if (requireUpdateChildren)
                {
                    base.UpdateChildren(tracker, e);
                    tracker.CleanUp();
                    TreeViewItemViewModel.AddModelProperty(this, this.Value, tracker.ParentProperty, tracker.ParentProperty);
                }
            }

            if (this.PerfEventProvider != null)
            {
                this.PerfEventProvider.DesignerTreeViewUpdateEnd();
            }
        }
        internal static void AddChild(TreeViewItemViewModel parent, ModelItem item, object value, bool duplicatedNodeVisible, string childNodePrefix, ModelProperty trackingProperty)
        {
            // If necessary, evaluate uniqueness of given item
            bool isUnique = false;

            if (!duplicatedNodeVisible)
            {
                // Note: These evaluations expect item to be an immediate child of trackingProperty.Value
                // Intermediate nodes would for example undermine simple check just below
                //
                // Caveat 1: Aim is to greatly reduce, not to eliminate, display of nodes visible elsewhere
                // Caveat 1a: Nodes reachable from other isolated nodes are included in the collection
                // Caveat 1b: Nodes that are not isolated may be reachable from isolated nodes and thus
                // displayed together with the isolated ones; ShowPropertyInOutlineViewAsSiblingAttribute may make this seem normal
                // (If complete duplicate elimination were the aim, would likely need a "never expand"
                // display mode for duplicateNodeVisible=false children)
                // Caveat 2: Use of single uniqueChildren field may cause all children of a second
                // duplcatedNodeVisible=false property to be ignored if (fortunately only if) neither
                // property uses ShowPropertyInOutlineViewAttribute(true) -- that attribute's default
                // Caveat 3-n: Please see caveats described at top of UniqueModelItemHelper
                if (1 >= item.Parents.Count())
                {
                    isUnique = true;
                }
                else
                {
                    // Avoided a thorough evaluation as long as we can
                    if (null == parent.uniqueChildren)
                    {
                        parent.uniqueChildren = UniqueModelItemHelper.FindUniqueChildren(trackingProperty);
                    }

                    isUnique = parent.uniqueChildren.Contains(item);
                }
            }

            // If displayable now, create the view model node
            if (duplicatedNodeVisible || isUnique)
            {
                TreeViewItemViewModel child = TreeViewItemViewModel.CreateViewModel(parent, value);
                child.NodePrefixText = childNodePrefix;
                parent.AddChild(child, trackingProperty);
            }
            // Track for potential addition or removal of parents even if not presently visible
            if (!duplicatedNodeVisible)
            {
                ModelItemImpl itemImpl = item as ModelItemImpl;
                if (null != itemImpl)
                {
                    ChangeNotificationTracker tracker = parent.GetTracker(trackingProperty);
                    tracker.AddCollection(itemImpl.InternalParents);
                    tracker.AddCollection(itemImpl.InternalSources);
                }
            }
        }
        internal virtual int FindInsertionIndex(ChangeNotificationTracker tracker)
        {
            int insertIndex = 0;

            if (tracker != null && tracker.ChildViewModels != null && tracker.ChildViewModels.Count > 0)
            {
                //assume the childViewModels are in order
                insertIndex = this.InternalChildren.IndexOf(tracker.ChildViewModels.Last()) + 1;
            }
            return(insertIndex);
        }
        internal virtual ChangeNotificationTracker GetTracker(ModelProperty modelProperty, bool createNew)
        {
            ChangeNotificationTracker tracker = null;

            if (!this.Trackers.TryGetValue(modelProperty, out tracker) && createNew)
            {
                tracker = new ChangeNotificationTracker(this, modelProperty);
                Trackers.Add(modelProperty, tracker);
            }
            return(tracker);
        }
        internal ChangeNotificationTracker GetTracker(TreeViewItemViewModel child)
        {
            ChangeNotificationTracker trackerForChild = null;

            foreach (ChangeNotificationTracker tracker in this.Trackers.Values)
            {
                if (tracker.ChildViewModels.Contains(child))
                {
                    trackerForChild = tracker;
                    break;
                }
            }
            Fx.Assert(trackerForChild != null, "Tracker should not be null");
            return(trackerForChild);
        }
        internal override ChangeNotificationTracker GetTracker(ModelProperty modelProperty, bool createNew)
        {
            ChangeNotificationTracker tracker = base.GetTracker(modelProperty, createNew);

            if (createNew)
            {
                Fx.Assert(this.Value == modelProperty, "The modelProperty should be the same as this.Value.");
                tracker.Add(modelProperty.Parent, modelProperty);
                ShowInOutlineViewAttribute viewVisible = ExtensibilityAccessor.GetAttribute <ShowInOutlineViewAttribute>(modelProperty);
                if (viewVisible != null && !string.IsNullOrWhiteSpace(viewVisible.PromotedProperty))
                {
                    ModelProperty promotedProperty = modelProperty.Value.Properties.Find(viewVisible.PromotedProperty);
                    tracker.Add(promotedProperty.Parent, promotedProperty);
                }
            }

            return(tracker);
        }
        internal override void UpdateChildren(ChangeNotificationTracker tracker, EventArgs e)
        {
            if (this.PerfEventProvider != null)
            {
                this.PerfEventProvider.DesignerTreeViewUpdateStart();
            }

            base.UpdateChildren(tracker, e);
            tracker.CleanUp();
            if (this.Value.Value != null)
            {
                this.AddChild(TreeViewItemViewModel.CreateViewModel(this, this.Value.Value), tracker.ParentProperty);
            }

            if (this.PerfEventProvider != null)
            {
                this.PerfEventProvider.DesignerTreeViewUpdateEnd();
            }
        }
        internal override void UpdateChildren(ChangeNotificationTracker tracker, EventArgs e)
        {
            if (this.PerfEventProvider != null)
            {
                this.PerfEventProvider.DesignerTreeViewUpdateStart();
            }

            //
            base.UpdateChildren(tracker, e);
            tracker.CleanUp();
            this.InternalChildren.Clear();

            this.LoadChildren();

            if (this.PerfEventProvider != null)
            {
                this.PerfEventProvider.DesignerTreeViewUpdateEnd();
            }
        }
        internal override void LoadChildren()
        {
            if (this.PerfEventProvider != null)
            {
                this.PerfEventProvider.DesignerTreeViewLoadChildrenStart();
            }

            base.LoadChildren();
            if (this.Value.Value != null)
            {
                ChangeNotificationTracker tracker = this.Parent.GetTracker(this);

                this.AddChild(TreeViewItemViewModel.CreateViewModel(this, this.Value.Value), tracker.ParentProperty);
            }

            if (this.PerfEventProvider != null)
            {
                this.PerfEventProvider.DesignerTreeViewLoadChildrenEnd();
            }
        }
Beispiel #11
0
        internal override ChangeNotificationTracker GetTracker(ModelProperty modelProperty, bool createNew)
        {
            ChangeNotificationTracker tracker = base.GetTracker(modelProperty, createNew);

            if (createNew)
            {
                if (this.VisualValue == modelProperty.Parent)
                {
                    // If this TreeViewModelItem use Promopted property and the property belongs to Promoted activity
                    // add the tracked property by default.
                    tracker.Add(this.VisualValue, modelProperty);
                }
                else
                {
                    // If it's an model item, add the tracked property by default
                    tracker.Add(this.Value, modelProperty);
                }
            }

            return(tracker);
        }
        //if child is null then only add the modelProperty for tracking purpose
        internal virtual void AddChild(TreeViewItemViewModel child, ModelProperty modelProperty)
        {
            //check for duplicate first
            if (child != null)
            {
                object childValue = child.GetValue();
                if (!ChildrenValueCache.Contains(childValue))
                {
                    ChildrenValueCache.Add(childValue);
                }
                else
                {
                    child.CleanUp();
                    return;
                }
            }

            ChangeNotificationTracker tracker = GetTracker(modelProperty);

            if (child != null)
            {
                // May be adding a node before it's expanded; get rid of the dummy
                if (this.Children.Count == 1 && this.Children[0] == DummyNode)
                {
                    this.InternalChildren.Remove(DummyNode);
                }

                int insertIndex = this.FindInsertionIndex(tracker);
                this.InternalChildren.Insert(insertIndex, child);
                tracker.ChildViewModels.Add(child);
                if (child.HasSibling)
                {
                    //loading children rather than just add the sibling of the children
                    //if this turn out to be a big performance impact then we'll need to optimise this
                    child.LoadChildren();
                }
            }
        }
        internal static void AddModelProperty(TreeViewItemViewModel parent, ModelItem item, ModelProperty trackingProperty, ModelProperty property)
        {
            //in the case of multiple attributes, they go in this order
            //HidePropertyInOutlineViewAttribute
            //[item.ShowInOutlineViewAttribute.PromotedProperty = property.Name]. Set VisualValue by property and ignore itself. Usage ActivityDelegate, FlowStep.
            //ShowPropertyInOutlineViewAttribute
            //ShowPropertyInOutlineViewAsSiblingAttribute
            //ShowInOutlineViewAttribute
            ShowPropertyInOutlineViewAttribute viewChild = ExtensibilityAccessor.GetAttribute <ShowPropertyInOutlineViewAttribute>(property);

            if (ExtensibilityAccessor.GetAttribute <HidePropertyInOutlineViewAttribute>(property) != null)
            {
                //ignore
                return;
            }
            else if (IsPromotedProperty(item, property))
            {
                if (property.IsCollection)
                {
                    ModelItemCollection mc = property.Value as ModelItemCollection;
                    AddModelItemCollection(parent, mc, trackingProperty);
                }
                else if (property.IsDictionary)
                {
                    ModelItemDictionary dictionary = property.Dictionary;
                    AddModelItemDictionary(parent, dictionary, trackingProperty);
                }
                else
                {
                    parent.GetTracker(trackingProperty).Add(item, property);

                    //if property.Value is null, then this would not add any node
                    // Use promoted ModelItem's property to track, so pass null to AddModelItem method.
                    AddModelItem(parent, property.Value, null);
                }
            }
            else if (viewChild != null)
            {
                if (viewChild.CurrentPropertyVisible) //property node visible
                {
                    if (property.Value != null)
                    {
                        TreeViewItemViewModel childModel = TreeViewItemViewModel.CreateViewModel(parent, property);
                        childModel.DuplicatedNodeVisible = viewChild.DuplicatedChildNodesVisible;
                        parent.AddChild(childModel, trackingProperty);
                    }
                    else
                    {
                        //just add the notification tracker without adding the empty child
                        parent.GetTracker(trackingProperty, true).Add(item, trackingProperty);
                    }
                }
                else
                {
                    if (property.IsCollection)
                    {
                        ModelItemCollection mc = property.Value as ModelItemCollection;
                        AddModelItemCollection(parent, mc, trackingProperty);
                    }
                    else if (property.IsDictionary)
                    {
                        ModelItemDictionary dictionary = property.Dictionary;
                        AddModelItemDictionary(parent, dictionary, trackingProperty);
                    }
                    else
                    {
                        if (property.Value != null)
                        {
                            TreeViewItemViewModel childModel = TreeViewItemViewModel.CreateViewModel(parent, property.Value);
                            childModel.DuplicatedNodeVisible = viewChild.DuplicatedChildNodesVisible;
                            parent.AddChild(childModel, trackingProperty);
                        }
                        else
                        {
                            parent.GetTracker(trackingProperty).Add(item, property);
                        }
                    }
                }
            }
            else if (ExtensibilityAccessor.GetAttribute <ShowPropertyInOutlineViewAsSiblingAttribute>(property) != null)
            {
                //add notification to the tracker that is responsible for this node
                ChangeNotificationTracker tracker = parent.Parent.GetTracker(parent);
                tracker.Add(item, property);
                TreeViewItemViewModel siblingNode = null;
                if (property.Value != null)
                {
                    siblingNode = TreeViewItemViewModel.CreateViewModel(parent.Parent, property.Value);
                }
                parent.Parent.AddChild(siblingNode, tracker.ParentProperty);
            }
            else if (ExtensibilityAccessor.GetAttribute <ShowInOutlineViewAttribute>(property) != null)
            {
                if (property.Value != null)
                {
                    ShowInOutlineViewAttribute outlineView = ExtensibilityAccessor.GetAttribute <ShowInOutlineViewAttribute>(property);
                    if (string.IsNullOrWhiteSpace(outlineView.PromotedProperty))
                    {
                        parent.AddChild(TreeViewItemViewModel.CreateViewModel(parent, property), trackingProperty);
                    }
                    else
                    {
                        ModelProperty promotedProperty = property.Value.Properties.Find(outlineView.PromotedProperty);
                        if (promotedProperty == null)
                        {
                            throw FxTrace.Exception.AsError(new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, SR.PromotedPropertyNotFound, outlineView.PromotedProperty, property.Value.Name)));
                        }

                        // Add promoted ModelItem and property into tracker. So when property got changed, the grandparent of promoted ModelItem will be notified.
                        ChangeNotificationTracker tracker = parent.GetTracker(trackingProperty, true);
                        tracker.Add(property.Value, promotedProperty);

                        if (promotedProperty.Value == null)
                        {
                            tracker.Add(item, property);
                        }
                        else
                        {
                            parent.AddChild(TreeViewItemViewModel.CreateViewModel(parent, property), trackingProperty);
                        }
                    }
                }
                else
                {
                    parent.GetTracker(trackingProperty, true).Add(item, property);
                }
            }
            //if the values in the dictionary is viewvisible, note this only works with generic dictionary
            else if (property.IsDictionary && property.PropertyType.IsGenericType)
            {
                Type[] arguments = property.PropertyType.GetGenericArguments();
                if (ExtensibilityAccessor.GetAttribute <ShowInOutlineViewAttribute>(arguments[1]) != null)
                {
                    if (property.Value != null)
                    {
                        parent.AddChild(TreeViewItemViewModel.CreateViewModel(parent, property), trackingProperty);
                    }
                    else
                    {
                        parent.GetTracker(trackingProperty, true).Add(item, property);
                    }
                }
            }
        }
 internal virtual void UpdateChildren(ChangeNotificationTracker tracker, EventArgs e)
 {
     this.uniqueChildren = null;
 }
 internal virtual void UpdateChildren(ChangeNotificationTracker tracker, EventArgs e)
 {
     this.uniqueChildren = null;
 }
 internal virtual int FindInsertionIndex(ChangeNotificationTracker tracker)
 {
     int insertIndex = 0;
     if (tracker != null && tracker.ChildViewModels != null && tracker.ChildViewModels.Count > 0)
     {
         //assume the childViewModels are in order
         insertIndex = this.InternalChildren.IndexOf(tracker.ChildViewModels.Last()) + 1;
     }
     return insertIndex;
 }
 internal virtual ChangeNotificationTracker GetTracker(ModelProperty modelProperty, bool createNew)
 {
     ChangeNotificationTracker tracker = null;
     if (!this.Trackers.TryGetValue(modelProperty, out tracker) && createNew)
     {
         tracker = new ChangeNotificationTracker(this, modelProperty);
         Trackers.Add(modelProperty, tracker);
     }
     return tracker;
 }