private void Initialize(bool isUpdating) { var targetNodePath = ModelNodePath.GetChildPath(SourceNodePath, sourceNode, targetNode); if (targetNodePath == null || !targetNodePath.IsValid) { throw new InvalidOperationException("Unable to retrieve the path of the given model node."); } foreach (var command in targetNode.Commands) { var commandWrapper = new ModelNodeCommandWrapper(ServiceProvider, command, Path, Owner.Identifier, targetNodePath, Owner.ModelContainer, Owner.GetDirtiableViewModels(this)); AddCommand(commandWrapper); } if (!isPrimitive) { GenerateChildren(targetNode, targetNodePath, isUpdating); } isInitialized = true; if (Owner.ObservableViewModelService != null) { var data = Owner.ObservableViewModelService.RequestAssociatedData(this, isUpdating); SetValue(ref associatedData, data, "AssociatedData"); } CheckDynamicMemberConsistency(); }
private void GenerateChildren(IModelNode modelNode, ModelNodePath modelNodePath, bool isUpdating) { if (modelNode.Content.IsReference) { var referenceEnumerable = modelNode.Content.Reference as ReferenceEnumerable; if (referenceEnumerable != null) { foreach (var reference in referenceEnumerable) { // The type might be a boxed primitive type, such as float, if the collection has object as generic argument. // In this case, we must set the actual type to have type converter working, since they usually can't convert // a boxed float to double for example. Otherwise, we don't want to have a node type that is value-dependent. var type = reference.TargetNode != null && reference.TargetNode.Content.IsPrimitive ? reference.TargetNode.Content.Type : reference.Type; var observableNode = Create(Owner, null, false, this, modelNode, modelNodePath, type, reference.Index); observableNode.Initialize(isUpdating); AddChild(observableNode); } } } else { var dictionary = modelNode.Content.Descriptor as DictionaryDescriptor; var list = modelNode.Content.Descriptor as CollectionDescriptor; if (dictionary != null && modelNode.Content.Value != null) { // Dictionary of primitive objects foreach (var key in dictionary.GetKeys(modelNode.Content.Value)) { var observableChild = Create(Owner, null, true, this, modelNode, modelNodePath, dictionary.ValueType, key); observableChild.Initialize(isUpdating); AddChild(observableChild); } } else if (list != null && modelNode.Content.Value != null) { // List of primitive objects for (int i = 0; i < list.GetCollectionCount(modelNode.Content.Value); ++i) { var observableChild = Create(Owner, null, true, this, modelNode, modelNodePath, list.ElementType, i); observableChild.Initialize(isUpdating); AddChild(observableChild); } } else { // Single non-reference primitive object foreach (var child in modelNode.Children) { var childPath = ModelNodePath.GetChildPath(modelNodePath, modelNode, child); var observableChild = Create(Owner, child.Name, child.Content.IsPrimitive, this, child, childPath, child.Content.Type, null); observableChild.Initialize(isUpdating); AddChild(observableChild); } } } }
internal protected virtual void Initialize() { var targetNodePath = SourceNodePath.GetChildPath(SourceNode, targetNode); if (targetNodePath == null || !targetNodePath.IsValid) { throw new InvalidOperationException("Unable to retrieve the path of the given model node."); } if (!targetNode.Content.ShouldProcessReference && Index != null) { // When the references are not processed, there is no actual target node. // However, the commands need the index to be able to properly set the modified value targetNodePath = targetNodePath.PushElement(Index, ModelNodePath.ElementType.Index); } foreach (var command in targetNode.Commands) { var commandWrapper = new ModelNodeCommandWrapper(ServiceProvider, command, Path, Owner, targetNodePath, Owner.Dirtiables); AddCommand(commandWrapper); } if (!isPrimitive) { GenerateChildren(targetNode, targetNodePath); } isInitialized = true; if (Owner.ObservableViewModelService != null) { foreach (var key in AssociatedData.Keys.ToList()) { RemoveAssociatedData(key); } Owner.ObservableViewModelService.NotifyNodeInitialized(this); } FinalizeChildrenInitialization(); CheckDynamicMemberConsistency(); }
private void GenerateChildren(IModelNode modelNode, ModelNodePath modelNodePath) { if (modelNode.Content.IsReference && modelNode.Content.ShouldProcessReference) { var referenceEnumerable = modelNode.Content.Reference as ReferenceEnumerable; if (referenceEnumerable != null) { // If the reference should not be processed, we still need to create an observable node for each entry of the enumerable. // These observable nodes will have the same source node that their parent so we use this information to prevent // the infinite recursion that could occur due to the fact that these child nodes will have the same model nodes (like primitive types) // while holding an enumerable reference. //if (modelNode.Content.ShouldProcessReference || ModelNodeParent.sourceNode != modelNode) { foreach (var reference in referenceEnumerable) { // The type might be a boxed primitive type, such as float, if the collection has object as generic argument. // In this case, we must set the actual type to have type converter working, since they usually can't convert // a boxed float to double for example. Otherwise, we don't want to have a node type that is value-dependent. var type = reference.TargetNode != null && reference.TargetNode.Content.IsPrimitive ? reference.TargetNode.Content.Type : reference.Type; var observableNode = Owner.ObservableViewModelService.ObservableNodeFactory(Owner, null, false, modelNode, modelNodePath, type, reference.Index); AddChild(observableNode); observableNode.Initialize(); } } } } else { var dictionary = modelNode.Content.Descriptor as DictionaryDescriptor; var list = modelNode.Content.Descriptor as CollectionDescriptor; if (dictionary != null && modelNode.Content.Value != null) { // Dictionary of primitive objects foreach (var key in dictionary.GetKeys(modelNode.Content.Value)) { var observableChild = Owner.ObservableViewModelService.ObservableNodeFactory(Owner, null, true, modelNode, modelNodePath, dictionary.ValueType, key); AddChild(observableChild); observableChild.Initialize(); } } else if (list != null && modelNode.Content.Value != null) { // List of primitive objects for (int i = 0; i < list.GetCollectionCount(modelNode.Content.Value); ++i) { var observableChild = Owner.ObservableViewModelService.ObservableNodeFactory(Owner, null, true, modelNode, modelNodePath, list.ElementType, i); AddChild(observableChild); observableChild.Initialize(); } } else { // Single non-reference primitive object foreach (var child in modelNode.Children) { var childPath = modelNodePath.GetChildPath(modelNode, child); var observableChild = Owner.ObservableViewModelService.ObservableNodeFactory(Owner, child.Name, child.Content.IsPrimitive, child, childPath, child.Content.Type, null); AddChild(observableChild); observableChild.Initialize(); } } } }