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); } }
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); } }
public static string PrintHierarchy(this IObservableNode node, int indentation = 0) { var builder = new StringBuilder(); PrintHierarchyInternal(node, 0, builder); return(builder.ToString()); }
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); }
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; }
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); } }
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; }
/// <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); }
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; }
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); }
/// <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(); }
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); }
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; }
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")); }
/// <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> /// 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> /// 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); }