private void Update(object newValue, NodeIndex index, bool sendNotification) { if (index == NodeIndex.Empty) { throw new ArgumentException("index cannot be empty."); } var oldValue = Retrieve(index); ItemChangeEventArgs itemArgs = null; if (sendNotification) { itemArgs = new ItemChangeEventArgs(this, index, ContentChangeType.CollectionUpdate, oldValue, newValue); NotifyItemChanging(itemArgs); } var collectionDescriptor = Descriptor as CollectionDescriptor; var dictionaryDescriptor = Descriptor as DictionaryDescriptor; if (collectionDescriptor != null) { collectionDescriptor.SetValue(Value, index.Int, ConvertValue(newValue, collectionDescriptor.ElementType)); } else if (dictionaryDescriptor != null) { dictionaryDescriptor.SetValue(Value, index.Value, ConvertValue(newValue, dictionaryDescriptor.ValueType)); } else { throw new NotSupportedException("Unable to set the node value, the collection is unsupported"); } UpdateReferences(); if (sendNotification) { NotifyItemChanged(itemArgs); } }
public static IEnumerable <NodeIndex> GetIndices([NotNull] IGraphNode node) { if (node.Descriptor is CollectionDescriptor collectionDescriptor) { if (node.Descriptor.Category == DescriptorCategory.Set) { var enumerator = (node.Retrieve() as IEnumerable).GetEnumerator(); NodeIndex[] valueArr = new NodeIndex[collectionDescriptor.GetCollectionCount(node.Retrieve())]; int i = 0; while (enumerator.MoveNext()) { valueArr[i++] = new NodeIndex(enumerator.Current); } return(valueArr); } else { return(Enumerable.Range(0, collectionDescriptor.GetCollectionCount(node.Retrieve())).Select(x => new NodeIndex(x))); } } var dictionaryDescriptor = node.Descriptor as DictionaryDescriptor; return(dictionaryDescriptor?.GetKeys(node.Retrieve()).Cast <object>().Select(x => new NodeIndex(x))); }
protected virtual bool ShouldVisitTargetItem(IObjectNode collectionNode, NodeIndex index) { return(true); }
protected internal override bool ShouldVisitTargetItem(IObjectNode collectionNode, NodeIndex index) { return(linker.ShouldVisitTargetItem(collectionNode, index) && base.ShouldVisitTargetItem(collectionNode, index)); }
internal void SetOwnerContent(IGraphNode ownerNode, NodeIndex index) { boxedStructureOwner = (GraphNodeBase)ownerNode; boxedStructureOwnerIndex = index; }
protected internal override void UpdateFromMember(object newValue, NodeIndex index) { Update(newValue, index, true); }
/// <summary> /// Indicates whether the target node of the item corresponding to the given index in the collection contained in the given node should be visited or not. /// </summary> /// <param name="collectionNode">The node to evaluate.</param> /// <param name="index">The index of the item to evaluate.</param> /// <returns>True if the node of the item corresponding to the given index in the collection contained in the given node should be visited, false otherwise.</returns> /// <remarks>This method is invoked only when the given <see cref="IObjectNode"/> contains a collection with items being references.</remarks> protected internal virtual bool ShouldVisitTargetItem([NotNull] IObjectNode collectionNode, NodeIndex index) { if (collectionNode == null) { throw new ArgumentNullException(nameof(collectionNode)); } var target = collectionNode.IndexedTarget(index); return(!visitedNodes.Contains(target)); }
internal DynamicIndexedNode(IGraphNode node, NodeIndex index) : base(node) { this.index = index; }
protected static bool UpdateCollection([NotNull] IObjectNode node, object value, NodeIndex index) { if (IsIndexExisting(node, index)) { node.Update(value, index); return(true); } if (IsIndexValid(node, index)) { node.Add(value, index); return(true); } return(false); }
/// <summary> /// Updates this content from one of its member. /// </summary> /// <param name="newValue">The new value for this content.</param> /// <param name="index">new index of the value to update.</param> /// <remarks> /// This method is intended to update a boxed content when one of its member changes. /// It allows to properly update boxed structs. /// </remarks> protected internal abstract void UpdateFromMember(object newValue, NodeIndex index);
/// <inheritdoc/> public virtual object Retrieve(NodeIndex index) { return(Content.Retrieve(Value, index, Descriptor)); }
/// <inheritdoc/> public void Update(object newValue, NodeIndex index) { Update(newValue, index, true); }
public static NodePathElement CreateIndex(NodeIndex index) { return(new NodePathElement(index)); }
public static GraphNodePath From(IGraphNode root, [NotNull] MemberPath memberPath, out NodeIndex index) { if (memberPath == null) { throw new ArgumentNullException(nameof(memberPath)); } var result = new GraphNodePath(root); index = NodeIndex.Empty; var memberPathItems = memberPath.Decompose(); for (int i = 0; i < memberPathItems.Count; i++) { var memberPathItem = memberPathItems[i]; bool lastItem = i == memberPathItems.Count - 1; if (memberPathItem.MemberDescriptor != null) { result.PushMember(memberPathItem.MemberDescriptor.Name); } else if (memberPathItem.GetIndex() != null) { var localIndex = new NodeIndex(memberPathItem.GetIndex()); if (lastItem) { // If last item, we directly return the index rather than add it to the path index = localIndex; } else { result.PushIndex(localIndex); } } // Don't apply Target on last item if (!lastItem) { // If this is a reference, add a target element to the path var node = result.GetNode(); var objectReference = (node as IMemberNode)?.TargetReference; if (objectReference?.TargetNode != null) { result.PushTarget(); } } } return(result); }
public void PushIndex(NodeIndex index) => PushElement(index, ElementType.Index);