예제 #1
0
        /// <summary>
        /// Initializes a new instance of the <see cref="GraphNodeViewModel"/> class.
        /// </summary>
        /// <param name="ownerViewModel">The <see cref="GraphViewModel"/> that owns the new <see cref="GraphNodeViewModel"/>.</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="sourceNode">The model node bound to the new <see cref="GraphNodeViewModel"/>.</param>
        /// <param name="graphNodePath">The <see cref="GraphNodePath"/> corresponding to the given <see cref="sourceNode"/>.</param>
        /// <param name="index">The index of this content in the model node, when this node represent an item of a collection. <see cref="Index.Empty"/> must be passed otherwise</param>
        protected GraphNodeViewModel(GraphViewModel ownerViewModel, string baseName, bool isPrimitive, IContentNode sourceNode, GraphNodePath graphNodePath, Index index)
            : base(ownerViewModel, baseName, index)
        {
            if (sourceNode == null)
            {
                throw new ArgumentNullException(nameof(sourceNode));
            }
            if (baseName == null && index == null)
            {
                throw new ArgumentException("baseName and index can't be both null.");
            }

            this.isPrimitive = isPrimitive;
            SourceNode       = sourceNode;
            // By default we will always combine items of list of primitive items.
            CombineMode    = !index.IsEmpty && isPrimitive ? CombineMode.AlwaysCombine : CombineMode.CombineOnlyForAll;
            SourceNodePath = graphNodePath;

            // Override display name if available
            var memberDescriptor = GetMemberDescriptor() as MemberDescriptorBase;

            if (memberDescriptor != null)
            {
                if (index.IsEmpty)
                {
                    var displayAttribute = TypeDescriptorFactory.Default.AttributeRegistry.GetAttribute <DisplayAttribute>(memberDescriptor.MemberInfo);
                    if (!string.IsNullOrEmpty(displayAttribute?.Name))
                    {
                        DisplayName = displayAttribute.Name;
                    }
                    IsReadOnly = !memberDescriptor.HasSet;
                }
            }
        }
예제 #2
0
 protected NodeViewModel(GraphViewModel ownerViewModel, Index index)
     : base(ownerViewModel.ServiceProvider)
 {
     DependentProperties.Add(nameof(Path), new[] { nameof(DisplayPath) });
     Owner      = ownerViewModel;
     Index      = index;
     Guid       = Guid.NewGuid();
     IsVisible  = true;
     IsReadOnly = false;
 }
        /// <summary>
        /// Initializes a new instance of the <see cref="SingleNodeViewModel"/> class.
        /// </summary>
        /// <param name="ownerViewModel">The <see cref="GraphViewModel"/> that owns the new <see cref="SingleNodeViewModel"/>.</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="index">The index of this content in the model node, when this node represent an item of a collection. <see cref="Index.Empty"/> must be passed otherwise</param>
        protected SingleNodeViewModel(GraphViewModel ownerViewModel, string baseName, Index index)
            : base(ownerViewModel, index)
        {
            if (baseName == null && index == null)
            {
                throw new ArgumentException("baseName and index can't be both null.");
            }

            CombineMode = CombineMode.CombineOnlyForAll;
            SetName(baseName);
        }
예제 #4
0
 protected VirtualNodeViewModel(GraphViewModel owner, string name, bool isPrimitive, int?order, Index index, Func <object> getter, Action <object> setter)
     : base(owner, name, index)
 {
     if (getter == null)
     {
         throw new ArgumentNullException(nameof(getter));
     }
     Getter      = getter;
     Setter      = setter;
     Order       = order;
     IsPrimitive = isPrimitive;
     Name        = name;
 }
예제 #5
0
        public CombinedActionsContext(GraphViewModel owner, string actionName, string nodePath)
        {
            if (owner == null)
            {
                throw new ArgumentNullException(nameof(owner));
            }
            var service = owner.ServiceProvider.TryGet <IUndoRedoService>();

            if (service != null)
            {
                transaction = service.CreateTransaction();
                service.SetName(transaction, actionName);
            }
            this.owner    = owner;
            this.nodePath = nodePath;
        }
예제 #6
0
        public static GraphViewModel CombineViewModels(IViewModelServiceProvider serviceProvider, IReadOnlyCollection <GraphViewModel> viewModels)
        {
            if (serviceProvider == null)
            {
                throw new ArgumentNullException(nameof(serviceProvider));
            }
            if (viewModels == null)
            {
                throw new ArgumentNullException(nameof(viewModels));
            }
            var combinedViewModel = new GraphViewModel(serviceProvider);

            var rootNodes = new List <GraphNodeViewModel>();

            foreach (var viewModel in viewModels)
            {
                if (!(viewModel.RootNode is SingleNodeViewModel))
                {
                    throw new ArgumentException(@"The view models to combine must contains SingleNodeViewModel.", nameof(viewModels));
                }

                viewModel.Parent = combinedViewModel;
                combinedViewModel.children.Add(viewModel);
                var rootNode = (GraphNodeViewModel)viewModel.RootNode;
                rootNodes.Add(rootNode);
            }

            if (rootNodes.Count < 2)
            {
                throw new ArgumentException(@"Called CombineViewModels with a collection of view models that is either empty or containt just a single item.", nameof(viewModels));
            }

            // Find best match for the root node type
            var rootNodeType = rootNodes.First().Root.Type;

            if (rootNodes.Skip(1).Any(x => x.Type != rootNodeType))
            {
                rootNodeType = typeof(object);
            }

            var service          = serviceProvider.Get <GraphViewModelService>();
            var rootCombinedNode = service.CombinedNodeViewModelFactory(combinedViewModel, "Root", rootNodeType, rootNodes, Index.Empty);

            combinedViewModel.RootNode = rootCombinedNode;
            rootCombinedNode.Initialize();
            return(combinedViewModel);
        }
예제 #7
0
 private static CombinedNodeViewModel DefaultCreateCombinedNode(GraphViewModel ownerViewModel, string baseName, Type contentType, IEnumerable <SingleNodeViewModel> combinedNodes, Index index)
 {
     return(CombinedNodeViewModel.Create(ownerViewModel, baseName, contentType, combinedNodes, index));
 }
예제 #8
0
 private static GraphNodeViewModel DefaultCreateNode(GraphViewModel viewModel, string baseName, bool isPrimitive, IContentNode modelNode, GraphNodePath graphNodePath, Type contentType, Index index)
 {
     return(GraphNodeViewModel.Create(viewModel, baseName, isPrimitive, modelNode, graphNodePath, contentType, index));
 }
        protected CombinedNodeViewModel(GraphViewModel ownerViewModel, string name, IEnumerable <SingleNodeViewModel> combinedNodes, Index index)
            : base(ownerViewModel, index)
        {
            // ReSharper disable once DoNotCallOverridableMethodsInConstructor
            DependentProperties.Add(nameof(Value), new[] { nameof(HasMultipleValues), nameof(IsPrimitive), nameof(HasCollection), nameof(HasDictionary) });
            this.combinedNodes = new List <SingleNodeViewModel>(combinedNodes);
            Name        = name;
            DisplayName = this.combinedNodes.First().DisplayName;

            combinedNodeInitialValues         = new List <object>();
            distinctCombinedNodeInitialValues = new HashSet <object>();

            bool isReadOnly = false;
            bool isVisible  = false;
            bool nullOrder  = false;

            foreach (var node in this.combinedNodes)
            {
                if (node.IsDestroyed)
                {
                    throw new InvalidOperationException("One of the combined node is already disposed.");
                }

                if (node.IsReadOnly)
                {
                    isReadOnly = true;
                }

                if (node.IsVisible)
                {
                    isVisible = true;
                }

                if (node.Order == null)
                {
                    nullOrder = true;
                }

                if (order == node.Order || (!nullOrder && order == null))
                {
                    order = node.Order;
                }

                // Note: sometimes member info could be different for the same member if we select objects of types that inherit from another
                // This will just affect the view order, so it shouldn't be a problem.
                if (memberInfo == null)
                {
                    memberInfo = node.MemberInfo;
                }

                combinedNodeInitialValues.Add(node.Value);
                distinctCombinedNodeInitialValues.Add(node.Value);
            }
            IsReadOnly = isReadOnly;
            IsVisible  = isVisible;

            ResetInitialValues = new AnonymousCommand(ServiceProvider, () =>
            {
                using (Owner.BeginCombinedAction(Owner.FormatCombinedUpdateMessage(this, null), Path))
                {
                    CombinedNodes.Zip(combinedNodeInitialValues).ForEach(x => x.Item1.Value = x.Item2);
                    Refresh();
                }
            });
        }
        internal static CombinedNodeViewModel Create(GraphViewModel ownerViewModel, string name, Type contentType, IEnumerable <SingleNodeViewModel> combinedNodes, Index index)
        {
            var node = (CombinedNodeViewModel)Activator.CreateInstance(typeof(CombinedNodeViewModel <>).MakeGenericType(contentType), ownerViewModel, name, combinedNodes, index);

            return(node);
        }
예제 #11
0
        /// <summary>
        /// Create an <see cref="GraphNodeViewModel{T}"/> that matches the given content type.
        /// </summary>
        /// <param name="ownerViewModel">The <see cref="GraphViewModel"/> that owns the new <see cref="GraphNodeViewModel"/>.</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="sourceNode">The model node bound to the new <see cref="GraphNodeViewModel"/>.</param>
        /// <param name="graphNodePath">The <see cref="GraphNodePath"/> corresponding to the given node.</param>
        /// <param name="contentType">The type of content contained by the new <see cref="GraphNodeViewModel"/>.</param>
        /// <param name="index">The index of this content in the model node, when this node represent an item of a collection. <see cref="Index.Empty"/> must be passed otherwise</param>
        /// <returns>A new instance of <see cref="GraphNodeViewModel{T}"/> instanced with the given content type as generic argument.</returns>
        internal static GraphNodeViewModel Create(GraphViewModel ownerViewModel, string baseName, bool isPrimitive, IContentNode sourceNode, GraphNodePath graphNodePath, Type contentType, Index index)
        {
            var node = (GraphNodeViewModel)Activator.CreateInstance(typeof(GraphNodeViewModel <>).MakeGenericType(contentType), ownerViewModel, baseName, isPrimitive, sourceNode, graphNodePath, index);

            return(node);
        }
예제 #12
0
 public GraphViewModelNodeValueChanged(GraphViewModel viewModel, string nodePath)
 {
     ViewModel = viewModel;
     NodePath  = nodePath;
 }