protected override void OnHeaderChanged(object oldHeader, object newHeader) { base.OnHeaderChanged(oldHeader, newHeader); TreeViewItemViewModel source = newHeader as TreeViewItemViewModel; if (source != null) { source.TreeViewItem = this; } }
internal ModelProperty GetTrackingModelPropertyForChild(TreeViewItemViewModel child) { ModelProperty property = null; foreach (ChangeNotificationTracker tracker in this.Trackers.Values) { if (tracker.ChildViewModels.Contains(child)) { property = tracker.ParentProperty; break; } } return(property); }
internal override void LoadChildren() { if (this.PerfEventProvider != null) { this.PerfEventProvider.DesignerTreeViewLoadChildrenStart(); } base.LoadChildren(); TreeViewItemViewModel.AddModelItem(this, this.Value, null); if (this.PerfEventProvider != null) { this.PerfEventProvider.DesignerTreeViewLoadChildrenEnd(); } }
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); }
public ChangeNotificationTracker(TreeViewItemViewModel parent, ModelProperty parentProperty) { if (parent == null) { throw FxTrace.Exception.AsError(new ArgumentNullException("parent")); } if (parentProperty == null) { throw FxTrace.Exception.AsError(new ArgumentNullException("parentProperty")); } this.Parent = parent; this.ParentProperty = parentProperty; this.TrackedModelItem = new Dictionary<ModelItem, HashSet<string>>(); this.TrackedCollection = new List<INotifyCollectionChanged>(); this.ChildViewModels = new List<TreeViewItemViewModel>(); }
internal static void AddModelItem(TreeViewItemViewModel parent, ModelItem item, ModelProperty trackingProperty) { if (item != null) { bool updateTrackingProperty = trackingProperty == null; foreach (ModelProperty property in item.Properties) { if (updateTrackingProperty) { trackingProperty = property; } AddModelProperty(parent, item, trackingProperty, property); } } }
internal Dictionary <string, string> GetAutomationItemStatus() { Dictionary <string, string> itemStatus = new Dictionary <string, string>(); TreeViewItemViewModel viewModel = this.Header as TreeViewItemViewModel; if (viewModel != null && viewModel.IsHighlighted) { itemStatus.Add("IsSelection", "True"); } else { itemStatus.Add("IsSelection", "False"); } return(itemStatus); }
public ChangeNotificationTracker(TreeViewItemViewModel parent, ModelProperty parentProperty) { if (parent == null) { throw FxTrace.Exception.AsError(new ArgumentNullException("parent")); } if (parentProperty == null) { throw FxTrace.Exception.AsError(new ArgumentNullException("parentProperty")); } this.Parent = parent; this.ParentProperty = parentProperty; this.TrackedModelItem = new Dictionary <ModelItem, HashSet <string> >(); this.TrackedCollection = new List <INotifyCollectionChanged>(); this.ChildViewModels = new List <TreeViewItemViewModel>(); }
public TreeViewItemModelPropertyViewModel(TreeViewItemViewModel parent, ModelProperty property) : base(parent) { Fx.Assert(property != null, "property cannot be null"); this.Value = property; this.VisualValue = property; if (property != null && property.Parent != null) { this.GetTracker(property); } this.UpdateState(); if (this.HasChildren) { this.InternalChildren.Add(TreeViewItemViewModel.DummyNode); } }
internal static TreeViewItemViewModel CreateViewModel(TreeViewItemViewModel parent, object value) { TreeViewItemViewModel viewModel = null; if (typeof(ModelItem).IsAssignableFrom(value.GetType())) { viewModel = new TreeViewItemModelItemViewModel(parent, value as ModelItem); } else if (typeof(ModelProperty).IsAssignableFrom(value.GetType())) { viewModel = new TreeViewItemModelPropertyViewModel(parent, value as ModelProperty); } else if (typeof(KeyValuePair <ModelItem, ModelItem>).IsAssignableFrom(value.GetType())) { viewModel = new TreeViewItemKeyValuePairModelItemViewModel(parent, (KeyValuePair <ModelItem, ModelItem>)value); } return(viewModel); }
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 static void AddModelItemCollection(TreeViewItemViewModel parent, ModelItemCollection collection, ModelProperty trackingProperty) { parent.GetTracker(trackingProperty).AddCollection(collection); bool duplicatedNodeVisible = true; string childNodePrefix = string.Empty; ShowPropertyInOutlineViewAttribute viewChild = ExtensibilityAccessor.GetAttribute <ShowPropertyInOutlineViewAttribute>(trackingProperty); if (viewChild != null) { duplicatedNodeVisible = viewChild.DuplicatedChildNodesVisible; childNodePrefix = viewChild.ChildNodePrefix; } foreach (ModelItem item in collection) { AddChild(parent, item, item, duplicatedNodeVisible, childNodePrefix, trackingProperty); } }
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(); } }
public TreeViewItemModelItemViewModel(TreeViewItemViewModel parent, ModelItem modelItem, bool lazyLoad) : base(parent) { this.Value = modelItem; ShowInOutlineViewAttribute attr = ExtensibilityAccessor.GetAttribute <ShowInOutlineViewAttribute>(modelItem); if (attr != null && !string.IsNullOrEmpty(attr.PromotedProperty)) { // Only consider one level of promoted property. this.promotedProperty = modelItem.Properties[attr.PromotedProperty]; if (this.promotedProperty != null) { this.VisualValue = this.promotedProperty.Value; } else { // is this what we really want? Fx.Assert(attr.PromotedProperty + " not found on " + modelItem.Name); this.VisualValue = null; } } else { this.VisualValue = modelItem; } IsHighlighted = Selection.IsSelection(this.VisualValue); if (lazyLoad) { this.UpdateState(); if (this.HasChildren) { this.InternalChildren.Add(TreeViewItemViewModel.DummyNode); } } else { this.LoadChildren(); } }
internal static void AddModelItemDictionary(TreeViewItemViewModel parent, ModelItemDictionary dictionary, ModelProperty trackingProperty) { parent.GetTracker(trackingProperty).AddCollection(dictionary); bool duplicatedNodeVisible = true; string childNodePrefix = string.Empty; ShowPropertyInOutlineViewAttribute viewChild = ExtensibilityAccessor.GetAttribute <ShowPropertyInOutlineViewAttribute>(trackingProperty); if (viewChild != null) { duplicatedNodeVisible = viewChild.DuplicatedChildNodesVisible; childNodePrefix = viewChild.ChildNodePrefix; } foreach (var pair in dictionary) { ModelItem item = null; //AddChild(parent, pair.Value, pair, duplicatedNodeVisible, trackingProperty); AddChild(parent, item, pair, duplicatedNodeVisible, childNodePrefix, trackingProperty); } }
//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(); } } }
protected override void OnUnselected(RoutedEventArgs e) { base.OnUnselected(e); if (shouldUpdateViewModel) { TreeViewItemViewModel viewModel = this.Header as TreeViewItemViewModel; if (viewModel != null) { if (viewModel is TreeViewItemModelPropertyViewModel || viewModel is TreeViewItemKeyValuePairModelItemViewModel) { viewModel.IsHighlighted = false; } else if (viewModel is TreeViewItemModelItemViewModel) { TreeViewItemModelItemViewModel modelItemViewModel = (TreeViewItemModelItemViewModel)viewModel; if (!modelItemViewModel.HasDesigner) { modelItemViewModel.IsHighlighted = false; } } } } }
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); } } } }
public TreeViewItemModelItemViewModel(TreeViewItemViewModel parent, ModelItem modelItem) : this(parent, modelItem, true) { }
private void HighlightTreeViewItemAndClearSelectionOnDesigner(TreeViewItemViewModel viewModel) { this.ParentTreeView.Context.Items.SetValue(new Selection()); viewModel.IsHighlighted = true; }
//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 AddModelItem(TreeViewItemViewModel parent, ModelItem item, ModelProperty trackingProperty) { if (item != null) { bool updateTrackingProperty = trackingProperty == null; foreach (ModelProperty property in item.Properties) { if (updateTrackingProperty) { trackingProperty = property; } AddModelProperty(parent, item, trackingProperty, property); } } }
internal static TreeViewItemViewModel CreateViewModel(TreeViewItemViewModel parent, object value) { TreeViewItemViewModel viewModel = null; if (typeof(ModelItem).IsAssignableFrom(value.GetType())) { viewModel = new TreeViewItemModelItemViewModel(parent, value as ModelItem); } else if (typeof(ModelProperty).IsAssignableFrom(value.GetType())) { viewModel = new TreeViewItemModelPropertyViewModel(parent, value as ModelProperty); } else if (typeof(KeyValuePair<ModelItem, ModelItem>).IsAssignableFrom(value.GetType())) { viewModel = new TreeViewItemKeyValuePairModelItemViewModel(parent, (KeyValuePair<ModelItem, ModelItem>)value); } return viewModel; }
internal static void AddModelItemCollection(TreeViewItemViewModel parent, ModelItemCollection collection, ModelProperty trackingProperty) { parent.GetTracker(trackingProperty).AddCollection(collection); bool duplicatedNodeVisible = true; string childNodePrefix = string.Empty; ShowPropertyInOutlineViewAttribute viewChild = ExtensibilityAccessor.GetAttribute<ShowPropertyInOutlineViewAttribute>(trackingProperty); if (viewChild != null) { duplicatedNodeVisible = viewChild.DuplicatedChildNodesVisible; childNodePrefix = viewChild.ChildNodePrefix; } foreach (ModelItem item in collection) { AddChild(parent, item, item, duplicatedNodeVisible, childNodePrefix, trackingProperty); } }
internal ModelProperty GetTrackingModelPropertyForChild(TreeViewItemViewModel child) { ModelProperty property = null; foreach (ChangeNotificationTracker tracker in this.Trackers.Values) { if (tracker.ChildViewModels.Contains(child)) { property = tracker.ParentProperty; break; } } return property; }
private void HighlightTreeViewItemAndClearSelectionOnDesigner(TreeViewItemViewModel viewModel) { this.ParentTreeView.Context.Items.SetValue(new Selection()); viewModel.IsHighlighted = true; }
internal static void AddModelItemDictionary(TreeViewItemViewModel parent, ModelItemDictionary dictionary, ModelProperty trackingProperty) { parent.GetTracker(trackingProperty).AddCollection(dictionary); bool duplicatedNodeVisible = true; string childNodePrefix = string.Empty; ShowPropertyInOutlineViewAttribute viewChild = ExtensibilityAccessor.GetAttribute<ShowPropertyInOutlineViewAttribute>(trackingProperty); if (viewChild != null) { duplicatedNodeVisible = viewChild.DuplicatedChildNodesVisible; childNodePrefix = viewChild.ChildNodePrefix; } foreach (var pair in dictionary) { ModelItem item = null; //AddChild(parent, pair.Value, pair, duplicatedNodeVisible, trackingProperty); AddChild(parent, item, pair, duplicatedNodeVisible, childNodePrefix, trackingProperty); } }
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 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 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; }