Beispiel #1
0
        private static void PrintHierarchyInternal(IObservableNode node, int indentation, StringBuilder builder)
        {
            PrintIndentation(indentation, builder);
            builder.Append(node.Name ?? "<untitled>");
            if (node.Index != null)
            {
                builder.Append("[");
                builder.Append(node.Index);
                builder.Append("]");
            }
            builder.Append(": [");
            builder.Append(node.Type.Name);
            builder.Append("] = ");
            builder.Append(node.Value == null ? "(null)" : node.Value.ToString().Replace(Environment.NewLine, " "));

            if (node.Commands.Any())
            {
                builder.Append("Cmd: ");
                foreach (var command in node.Commands)
                {
                    builder.Append("(");
                    builder.Append(((NodeCommandWrapperBase)command).Name);
                    builder.Append(")");
                }
            }
            builder.AppendLine();
            foreach (var child in node.Children)
            {
                PrintHierarchyInternal(child, indentation + 4, builder);
            }
        }
Beispiel #2
0
        private static void PrintHierarchyInternal(IObservableNode node, int indentation, StringBuilder builder)
        {
            PrintIndentation(indentation, builder);
            builder.Append(node.Name ?? "<untitled>");
            if (!node.Index.IsEmpty)
            {
                builder.Append("[");
                builder.Append(node.Index);
                builder.Append("]");
            }
            builder.Append(": [");
            builder.Append(node.Type.Name);
            builder.Append("] = ");
            builder.Append(node.Value?.ToString().Replace(Environment.NewLine, " ") ?? "(null)");

            if (node.Commands.Any())
            {
                builder.Append("Cmd: ");
                foreach (var command in node.Commands)
                {
                    builder.Append("(");
                    builder.Append(((NodeCommandWrapperBase)command).Name);
                    builder.Append(")");
                }
            }
            builder.AppendLine();
            foreach (var child in node.Children)
            {
                PrintHierarchyInternal(child, indentation + 4, builder);
            }
        }
Beispiel #3
0
        public static string PrintHierarchy(this IObservableNode node, int indentation = 0)
        {
            var builder = new StringBuilder();

            PrintHierarchyInternal(node, 0, builder);
            return(builder.ToString());
        }
Beispiel #4
0
        private static int CompareChildren(IObservableNode a, IObservableNode b)
        {
            // Order has the best priority for comparison, if set.
            if (a.Order != null && b.Order != null)
            {
                return(((int)a.Order).CompareTo(b.Order));
            }

            // Then we use index, if they are set and comparable.
            if (a.Index != null && b.Index != null)
            {
                if (a.Index.GetType() == b.Index.GetType() && a.Index is IComparable)
                {
                    return(((IComparable)a.Index).CompareTo(b.Index));
                }
            }

            // Then we use name, only if both orders are unset.
            if (a.Order == null && b.Order == null)
            {
                return(string.Compare(a.Name, b.Name, StringComparison.InvariantCultureIgnoreCase));
            }

            // Otherwise, the first child would be the one who have an order value.
            return(a.Order == null ? 1 : -1);
        }
Beispiel #5
0
 protected ObservableNode(ObservableViewModel ownerViewModel, IObservableNode parentNode, object index = null)
     : base(ownerViewModel.ServiceProvider)
 {
     Owner      = ownerViewModel;
     Parent     = parentNode;
     Index      = index;
     Guid       = Guid.NewGuid();
     IsVisible  = true;
     IsReadOnly = false;
 }
Beispiel #6
0
 public static void AssertHierarchy(this IObservableNode node)
 {
     foreach (var child in node.Children)
     {
         if (child.Parent != node)
         {
             throw new Exception("Parent/Children mismatch");
         }
         AssertHierarchy(child);
     }
 }
Beispiel #7
0
 internal void RemoveChild(IObservableNode node)
 {
     if (node == null)
     {
         throw new ArgumentNullException("node");
     }
     if (!children.Contains(node))
     {
         throw new InvalidOperationException("The node is not in the children list of its parent.");
     }
     NotifyPropertyChanging(node.Name);
     children.Remove(node);
     NotifyPropertyChanged(node.Name);
 }
        /// <inheritdoc/>
        public override bool MatchNode(IObservableNode node)
        {
            if (Type == null)
                return true;

            if (MatchType(node, Type))
                return true;

            if (AcceptNullable && Type.IsValueType)
            {
                var nullableType = typeof(Nullable<>).MakeGenericType(new[] { Type });
                return MatchType(node, nullableType);
            }

            return false;
        }
Beispiel #9
0
        /// <summary>
        /// Indicates whether this node can be moved.
        /// </summary>
        /// <param name="newParent">The new parent of the node once moved.</param>
        /// <returns><c>true</c> if the node can be moved, <c>fals</c> otherwise.</returns>
        public bool CanMove(IObservableNode newParent)
        {
            if (newParent is CombinedObservableNode)
            {
                return(false);
            }

            var parent = newParent;

            while (parent != null)
            {
                if (parent == this)
                {
                    return(false);
                }
                parent = parent.Parent;
            }
            return(true);
        }
        /// <inheritdoc/>
        public override bool MatchNode(IObservableNode node)
        {
            if (Type == null)
            {
                return(false);
            }

            if (MatchType(node, Type))
            {
                return(true);
            }

            if (AcceptNullable && Type.IsValueType)
            {
                var nullableType = typeof(Nullable <>).MakeGenericType(new[] { Type });
                return(MatchType(node, nullableType));
            }

            return(false);
        }
Beispiel #11
0
        internal void AddChild(IObservableNode node)
        {
            if (node == null)
            {
                throw new ArgumentNullException("node");
            }
            if (children.Contains(node))
            {
                throw new InvalidOperationException("The node is already in the children list of its parent.");
            }
            NotifyPropertyChanging(node.Name);
            children.Add(node);
            NotifyPropertyChanged(node.Name);

            if (node.IsVisible)
            {
                ++VisibleChildrenCount;
            }
            node.IsVisibleChanged += ChildVisibilityChanged;
        }
Beispiel #12
0
        internal IDictionary <string, object> RequestAssociatedData(IObservableNode node, bool updatingData)
        {
            var mergedResult = new Dictionary <string, object>();

            foreach (var provider in associatedDataProviders)
            {
                var data = new Dictionary <string, object>();
                provider(node, data);
                // We use the Add method the first time to prevent unspotted key collision.
                if (updatingData)
                {
                    data.ForEach(x => mergedResult.Add(x.Key, x.Value));
                }
                else
                {
                    data.ForEach(x => mergedResult[x.Key] = x.Value);
                }
            }
            return(mergedResult);
        }
Beispiel #13
0
        /// <summary>
        /// Moves the node by setting it a new parent.
        /// </summary>
        /// <param name="newParent">The new parent of the node once moved.</param>
        /// <param name="newName">The new name to give to the node once moved. This will modify its path. If <c>null</c>, it does not modify the name.</param>
        public void Move(IObservableNode newParent, string newName = null)
        {
            if (this is CombinedObservableNode)
            {
                throw new InvalidOperationException("A CombinedObservableNode cannot be moved.");
            }
            if (newParent is CombinedObservableNode)
            {
                throw new ArgumentException("The new parent cannot be a CombinedObservableNode");
            }

            var parent = (ObservableNode)newParent;

            while (parent != null)
            {
                if (parent == this)
                {
                    throw new InvalidOperationException("A node cannot be moved into itself or one of its children.");
                }
                parent = (ObservableNode)parent.Parent;
            }

            if (newParent.Children.Any(x => (newName == null && x.Name == Name) || x.Name == newName))
            {
                throw new InvalidOperationException("Unable to move this node, a node with the same name already exists.");
            }

            if (Parent != null)
            {
                parent = (ObservableNode)Parent;
                parent.RemoveChild(this);
            }

            if (newName != null)
            {
                Name = newName;
            }
            Parent = newParent;
            ((ObservableNode)newParent).AddChild(this);
            UpdateCommandPath();
        }
Beispiel #14
0
        private static int CompareChildren(IObservableNode a, IObservableNode b)
        {
            // Order has the best priority for comparison, if set.
            if (a.Order != null && b.Order != null)
            {
                return(((int)a.Order).CompareTo(b.Order));
            }

            // If one has order and not the other one, consider the one with order as more prioritary
            if (a.Order != null)
            {
                return(-1);
            }
            if (b.Order != null)
            {
                return(1);
            }

            // Then we use index, if they are set and comparable.
            if (!a.Index.IsEmpty && !b.Index.IsEmpty)
            {
                if (a.Index.Value.GetType() == b.Index.Value.GetType())
                {
                    return(a.Index.CompareTo(b.Index));
                }
            }

            // Then we use name, only if both orders are unset.
            if (a.Order == null && b.Order == null)
            {
                return(string.Compare(a.Name, b.Name, StringComparison.InvariantCultureIgnoreCase));
            }

            // Otherwise, the first child would be the one who have an order value.
            return(a.Order == null ? 1 : -1);
        }
Beispiel #15
0
        private static int CompareChildren(IObservableNode a, IObservableNode b)
        {
            // Order has the best priority for comparison, if set.
            if ((a.Order ?? 0) != (b.Order ?? 0))
            {
                return((a.Order ?? 0).CompareTo(b.Order ?? 0));
            }

            // Then we use index, if they are set and comparable.
            if (!a.Index.IsEmpty && !b.Index.IsEmpty)
            {
                if (a.Index.Value.GetType() == b.Index.Value.GetType())
                {
                    return(a.Index.CompareTo(b.Index));
                }
            }

            // Then, try to use metadata token (if members)
            if (a.MemberInfo != null || b.MemberInfo != null)
            {
                var comparison = a.MemberInfo.CompareMetadataTokenWith(b.MemberInfo);
                if (comparison != 0)
                {
                    return(comparison);
                }
            }

            // Then we use name, only if both orders are unset.
            if (a.Order == null && b.Order == null)
            {
                return(string.Compare(a.Name, b.Name, StringComparison.InvariantCultureIgnoreCase));
            }

            // Otherwise, the first child would be the one who have an order value.
            return(a.Order == null ? 1 : -1);
        }
        /// <summary>
        /// Indicates whether this node can be moved.
        /// </summary>
        /// <param name="newParent">The new parent of the node once moved.</param>
        /// <returns><c>true</c> if the node can be moved, <c>fals</c> otherwise.</returns>
        public bool CanMove(IObservableNode newParent)
        {
            if (newParent is CombinedObservableNode)
                return false;

            var parent = newParent;
            while (parent != null)
            {
                if (parent == this)
                    return false;
                parent = parent.Parent;
            }
            return true;
        }
Beispiel #17
0
        private static int CompareChildren(IObservableNode a, IObservableNode b)
        {
            // Order has the best priority for comparison, if set.
            if (a.Order != null && b.Order != null)
                return ((int)a.Order).CompareTo(b.Order);

            // If one has order and not the other one, consider the one with order as more prioritary
            if (a.Order != null)
                return -1;
            if (b.Order != null)
                return 1;

            // Then we use index, if they are set and comparable.
            if (a.Index != null && b.Index != null)
            {
                if (a.Index.GetType() == b.Index.GetType() && a.Index is IComparable)
                {
                    return ((IComparable)a.Index).CompareTo(b.Index);
                }
            }

            // Then we use name, only if both orders are unset.
            if (a.Order == null && b.Order == null)
                return string.Compare(a.Name, b.Name, StringComparison.InvariantCultureIgnoreCase);

            // Otherwise, the first child would be the one who have an order value.
            return a.Order == null ? 1 : -1;
        }
 /// <summary>
 /// Indicates whether the given node matches the given type, either with the <see cref="IObservableNode.Type"/> property
 /// or the type of the <see cref="IObservableNode.Value"/> property.
 /// </summary>
 /// <param name="node">The node to check.</param>
 /// <param name="type">The type to match.</param>
 /// <returns><c>true</c> if the node matches the given type, <c>false</c> otherwise.</returns>
 protected static bool MatchType(IObservableNode node, Type type)
 {
     return type.IsAssignableFrom(node.Type) || type.IsInstanceOfType(node.Value);
 }
 public override bool MatchNode(IObservableNode node)
 {
     return node.Type.IsNumeric() && node.AssociatedData.ContainsKey("Minimum") && node.AssociatedData.ContainsKey("Maximum")
            && node.AssociatedData.ContainsKey("SmallStep") && node.AssociatedData.ContainsKey("LargeStep");
 }
 public override bool MatchNode(IObservableNode node)
 {
     return(node.Type.IsNumeric() && node.AssociatedData.ContainsKey("Minimum") && node.AssociatedData.ContainsKey("Maximum") &&
            node.AssociatedData.ContainsKey("SmallStep") && node.AssociatedData.ContainsKey("LargeStep"));
 }
Beispiel #21
0
 /// <summary>
 /// Indicates whether this instance of <see cref="ITemplateProvider"/> can provide a template for the given <see cref="IObservableNode"/>.
 /// </summary>
 /// <param name="node">The node to test.</param>
 /// <returns><c>true</c> if this template provider can provide a template for the given node, <c>false</c> otherwise.</returns>
 /// <remarks>This method is invoked by <see cref="Match"/>.</remarks>
 public abstract bool MatchNode(IObservableNode node);
Beispiel #22
0
 /// <summary>
 /// Indicates whether the given node matches the given type, either with the <see cref="IObservableNode.Type"/> property
 /// or the type of the <see cref="IObservableNode.Value"/> property.
 /// </summary>
 /// <param name="node">The node to check.</param>
 /// <param name="type">The type to match.</param>
 /// <returns><c>true</c> if the node matches the given type, <c>false</c> otherwise.</returns>
 protected static bool MatchType(IObservableNode node, Type type)
 {
     return(type.IsAssignableFrom(node.Type) || type.IsInstanceOfType(node.Value));
 }
 /// <summary>
 /// Indicates whether this instance of <see cref="ITemplateProvider"/> can provide a template for the given <see cref="IObservableNode"/>.
 /// </summary>
 /// <param name="node">The node to test.</param>
 /// <returns><c>true</c> if this template provider can provide a template for the given node, <c>false</c> otherwise.</returns>    
 /// <remarks>This method is invoked by <see cref="Match"/>.</remarks> 
 public abstract bool MatchNode(IObservableNode node);
        /// <summary>
        /// Moves the node by setting it a new parent.
        /// </summary>
        /// <param name="newParent">The new parent of the node once moved.</param>
        /// <param name="newName">The new name to give to the node once moved. This will modify its path. If <c>null</c>, it does not modify the name.</param>
        public void Move(IObservableNode newParent, string newName = null)
        {
            if (this is CombinedObservableNode)
                throw new InvalidOperationException("A CombinedObservableNode cannot be moved.");
            if (newParent is CombinedObservableNode)
                throw new ArgumentException("The new parent cannot be a CombinedObservableNode");

            var parent = (ObservableNode)newParent;
            while (parent != null)
            {
                if (parent == this)
                    throw new InvalidOperationException("A node cannot be moved into itself or one of its children.");
                parent = (ObservableNode)parent.Parent;
            }

            if (newParent.Children.Any(x => (newName == null && x.Name == Name) || x.Name == newName))
                throw new InvalidOperationException("Unable to move this node, a node with the same name already exists.");

            if (Parent != null)
            {
                parent = (ObservableNode)Parent;
                parent.RemoveChild(this);
            }

            if (newName != null)
            {
                Name = newName;
            }
            ((ObservableNode)newParent).AddChild(this);
        }
        private static int CompareChildren(IObservableNode a, IObservableNode b)
        {
            // Order has the best priority for comparison, if set.
            if ((a.Order ?? 0) != (b.Order ?? 0))
                return (a.Order ?? 0).CompareTo(b.Order ?? 0);

            // Then we use index, if they are set and comparable.
            if (!a.Index.IsEmpty && !b.Index.IsEmpty)
            {
                if (a.Index.Value.GetType() == b.Index.Value.GetType())
                {
                    return a.Index.CompareTo(b.Index); 
                }
            }

            // Then, try to use metadata token (if members)
            if (a.MemberInfo != null || b.MemberInfo != null)
            {
                var comparison = a.MemberInfo.CompareMetadataTokenWith(b.MemberInfo);
                if (comparison != 0)
                    return comparison;
            }

            // Then we use name, only if both orders are unset.
            if (a.Order == null && b.Order == null)
            {
                return string.Compare(a.Name, b.Name, StringComparison.InvariantCultureIgnoreCase);
            }

            // Otherwise, the first child would be the one who have an order value.
            return a.Order == null ? 1 : -1;
        }
        internal static VirtualObservableNode Create(ObservableViewModel ownerViewModel, string name, IObservableNode parentNode, int?order, Type contentType, object initialValue, NodeCommandWrapperBase valueChangedCommand)
        {
            var node = (VirtualObservableNode)Activator.CreateInstance(typeof(VirtualObservableNode <>).MakeGenericType(contentType), ownerViewModel, name, parentNode, order, initialValue, valueChangedCommand);

            return(node);
        }