Beispiel #1
0
        private void Initialize(bool isUpdating)
        {
            var path = ModelNodePath.GetPath(((ObservableModelNode)Root).sourceNode, targetNode);

            if (!path.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, path, Owner.ModelContainer, Owner.GetDirtiableViewModels(this));
                AddCommand(commandWrapper);
            }

            if (!isPrimitive)
            {
                GenerateChildren(targetNode, isUpdating);
            }

            isInitialized = true;

            if (Owner.ObservableViewModelService != null)
            {
                var data = Owner.ObservableViewModelService.RequestAssociatedData(this, isUpdating);
                SetValue(ref associatedData, data, "AssociatedData");
            }

            CheckDynamicMemberConsistency();
        }
Beispiel #2
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ObservableModelNode"/> class.
        /// </summary>
        /// <param name="ownerViewModel">The <see cref="ObservableViewModel"/> that owns the new <see cref="ObservableModelNode"/>.</param>
        /// <param name="baseName">The base name of this node. Can be null if <see cref="index"/> is not. If so a name will be automatically generated from the index.</param>
        /// <param name="isPrimitive">Indicate whether this node should be considered as a primitive node.</param>
        /// <param name="modelNode">The model node bound to the new <see cref="ObservableModelNode"/>.</param>
        /// <param name="modelNodePath">The <see cref="ModelNodePath"/> corresponding to the given <see cref="modelNode"/>.</param>
        /// <param name="index">The index of this content in the model node, when this node represent an item of a collection. <c>null</c> must be passed otherwise</param>
        protected ObservableModelNode(ObservableViewModel ownerViewModel, string baseName, bool isPrimitive, IModelNode modelNode, ModelNodePath modelNodePath, object index = null)
            : base(ownerViewModel, baseName, index)
        {
            if (modelNode == null)
            {
                throw new ArgumentNullException("modelNode");
            }
            if (baseName == null && index == null)
            {
                throw new ArgumentException("baseName and index can't be both null.");
            }

            this.isPrimitive = isPrimitive;
            SourceNode       = modelNode;
            // By default we will always combine items of list of primitive items.
            CombineMode    = index != null && isPrimitive ? CombineMode.AlwaysCombine : CombineMode.CombineOnlyForAll;
            targetNode     = GetTargetNode(modelNode, index);
            SourceNodePath = modelNodePath;

            // Override display name if available
            if (index == null)
            {
                var memberDescriptor = GetMemberDescriptor() as MemberDescriptorBase;
                if (memberDescriptor != null)
                {
                    var displayAttribute = TypeDescriptorFactory.Default.AttributeRegistry.GetAttribute <DisplayAttribute>(memberDescriptor.MemberInfo);
                    if (displayAttribute != null && !string.IsNullOrEmpty(displayAttribute.Name))
                    {
                        DisplayName = displayAttribute.Name;
                    }
                }
            }
        }
Beispiel #3
0
        internal void RegisterAction(string displayName, ModelNodePath nodePath, string observableNodePath, object index, IReadOnlyCollection <IDirtiableViewModel> dirtiables, object newValue, object previousValue)
        {
            singleNodeActionRegistered = true;
            var actionItem = new ValueChangedActionItem(displayName, observableViewModelService, nodePath, observableNodePath, Identifier, index, dirtiables, modelContainer, previousValue);

            ActionStack.Add(actionItem);
            NotifyNodeChanged(observableNodePath);
        }
 protected override void FreezeMembers()
 {
     service            = null;
     NodePath           = null;
     ObservableNodePath = null;
     Index         = null;
     PreviousValue = null;
 }
Beispiel #5
0
 protected override void FreezeMembers()
 {
     service            = null;
     modelContainer     = null;
     nodePath           = null;
     observableNodePath = null;
     index = null;
 }
Beispiel #6
0
 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);
             }
         }
     }
 }
 public ValueChangedActionItem(string name, ObservableViewModelService service, ModelNodePath nodePath, string observableNodePath, ObservableViewModelIdentifier identifier, object index, IEnumerable <IDirtiableViewModel> dirtiables, object previousValue)
     : base(name, dirtiables)
 {
     if (service == null)
     {
         throw new ArgumentNullException("service");
     }
     if (!nodePath.IsValid)
     {
         throw new InvalidOperationException("Unable to retrieve the path of the modified node.");
     }
     this.service       = service;
     this.identifier    = identifier;
     this.PreviousValue = previousValue;
     NodePath           = nodePath;
     Index = index;
     ObservableNodePath = observableNodePath;
 }
Beispiel #8
0
 public ModelNodeCommandWrapper(IViewModelServiceProvider serviceProvider, INodeCommand nodeCommand, string observableNodePath, ObservableViewModelIdentifier identifier, ModelNodePath nodePath, ModelContainer modelContainer, IEnumerable <IDirtiableViewModel> dirtiables)
     : base(serviceProvider, dirtiables)
 {
     if (nodeCommand == null)
     {
         throw new ArgumentNullException("nodeCommand");
     }
     if (modelContainer == null)
     {
         throw new ArgumentNullException("modelContainer");
     }
     this.identifier     = identifier;
     this.nodePath       = nodePath;
     this.modelContainer = modelContainer;
     this.nodeCommand    = nodeCommand;
     service             = serviceProvider.Get <ObservableViewModelService>();
     ObservableNodePath  = observableNodePath;
 }
Beispiel #9
0
 public ModelNodeCommandWrapper(IViewModelServiceProvider serviceProvider, INodeCommand nodeCommand, string observableNodePath, ObservableViewModel owner, ModelNodePath nodePath, IEnumerable <IDirtiableViewModel> dirtiables)
     : base(serviceProvider, dirtiables)
 {
     if (nodeCommand == null)
     {
         throw new ArgumentNullException(nameof(nodeCommand));
     }
     if (owner == null)
     {
         throw new ArgumentNullException(nameof(owner));
     }
     NodePath = nodePath;
     // Note: the owner should not be stored in the command because we want it to be garbage collectable
     Identifier         = owner.Identifier;
     ModelContainer     = owner.ModelContainer;
     NodeCommand        = nodeCommand;
     Service            = serviceProvider.Get <ObservableViewModelService>();
     ObservableNodePath = observableNodePath;
 }
Beispiel #10
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ObservableModelNode"/> class.
        /// </summary>
        /// <param name="ownerViewModel">The <see cref="ObservableViewModel"/> that owns the new <see cref="ObservableModelNode"/>.</param>
        /// <param name="baseName">The base name of this node. Can be null if <see cref="index"/> is not. If so a name will be automatically generated from the index.</param>
        /// <param name="isPrimitive">Indicate whether this node should be considered as a primitive node.</param>
        /// <param name="parentNode">The parent node of the new <see cref="ObservableModelNode"/>, or <c>null</c> if the node being created is the root node of the view model.</param>
        /// <param name="modelNode">The model node bound to the new <see cref="ObservableModelNode"/>.</param>
        /// <param name="modelNodePath">The <see cref="ModelNodePath"/> corresponding to the given <see cref="modelNode"/>.</param>
        /// <param name="index">The index of this content in the model node, when this node represent an item of a collection. <c>null</c> must be passed otherwise</param>
        protected ObservableModelNode(ObservableViewModel ownerViewModel, string baseName, bool isPrimitive, SingleObservableNode parentNode, IModelNode modelNode, ModelNodePath modelNodePath, object index = null)
            : base(ownerViewModel, baseName, parentNode, index)
        {
            if (modelNode == null)
            {
                throw new ArgumentNullException("modelNode");
            }
            if (baseName == null && index == null)
            {
                throw new ArgumentException("baseName and index can't be both null.");
            }

            this.isPrimitive = isPrimitive;
            sourceNode       = modelNode;
            // By default we will always combine items of list of primitive items.
            CombineMode    = index != null && isPrimitive ? CombineMode.AlwaysCombine : CombineMode.CombineOnlyForAll;
            targetNode     = GetTargetNode(modelNode, index);
            SourceNodePath = modelNodePath;
        }
Beispiel #11
0
 /// <summary>
 /// Retrieves a <see cref="ModelNodePath"/> object corresponding to the path of the model node contained in this <see cref="ObservableModelNode"/>.
 /// </summary>
 /// <returns>A <see cref="ModelNodePath"/> object corresponding to the path of the model node contained in this <see cref="ObservableModelNode"/>.</returns>
 public ModelNodePath GetModelNodePath()
 {
     return(ModelNodePath.GetPath(((ObservableModelNode)Root).sourceNode, sourceNode));
 }
Beispiel #12
0
        /// <summary>
        /// Create an <see cref="ObservableModelNode{T}"/> that matches the given content type.
        /// </summary>
        /// <param name="ownerViewModel">The <see cref="ObservableViewModel"/> that owns the new <see cref="ObservableModelNode"/>.</param>
        /// <param name="baseName">The base name of this node. Can be null if <see cref="index"/> is not. If so a name will be automatically generated from the index.</param>
        /// <param name="isPrimitive">Indicate whether this node should be considered as a primitive node.</param>
        /// <param name="modelNode">The model node bound to the new <see cref="ObservableModelNode"/>.</param>
        /// <param name="modelNodePath">The <see cref="ModelNodePath"/> corresponding to the given node.</param>
        /// <param name="contentType">The type of content contained by the new <see cref="ObservableModelNode"/>.</param>
        /// <param name="index">The index of this content in the model node, when this node represent an item of a collection. <c>null</c> must be passed otherwise</param>
        /// <returns>A new instance of <see cref="ObservableModelNode{T}"/> instanced with the given content type as generic argument.</returns>
        internal static ObservableModelNode Create(ObservableViewModel ownerViewModel, string baseName, bool isPrimitive, IModelNode modelNode, ModelNodePath modelNodePath, Type contentType, object index)
        {
            var node = (ObservableModelNode)Activator.CreateInstance(typeof(ObservableModelNode <>).MakeGenericType(contentType), ownerViewModel, baseName, isPrimitive, modelNode, modelNodePath, index);

            return(node);
        }
Beispiel #13
0
 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();
             }
         }
     }
 }
Beispiel #14
0
 private static ObservableModelNode DefaultCreateNode(ObservableViewModel viewModel, string baseName, bool isPrimitive, IModelNode modelNode, ModelNodePath modelNodePath, Type contentType, object index)
 {
     return(ObservableModelNode.Create(viewModel, baseName, isPrimitive, modelNode, modelNodePath, contentType, index));
 }