/// <summary> /// Add another search constraint. /// </summary> /// <param name="additionalSearch">Additional search constraint.</param> /// <returns>The conjunction.</returns> public Search <TControlPattern> And(ISearchPattern additionalSearch) { if (additionalSearch != null) { foreach (var p in additionalSearch.GetPatternItems()) { And(p.Key, p.Value); } } return(this); }
/// <inheritdoc/> public override void Init(ISearchPattern pattern, Predicate <IControl> predicate) { ControlPattern conjunction = new ControlPattern(); if (pattern != null) { foreach (var p in pattern.GetPatternItems()) { conjunction.Add(p.Key, p.Value); } } foreach (var p in SearchPattern.GetPatternItems()) { if (!conjunction.GetPatternItems().Any(e => e.Key == p.Key)) { conjunction.Add(p.Key, p.Value); } } base.Init(conjunction, predicate); }
/// <summary> /// Finds all nodes with the given full class name. /// </summary> /// <param name="source">The node to search from.</param> /// <param name="pattern">The search pattern.</param> /// <param name="depth">The search depth.</param> /// <returns>The enumeration nodes.</returns> /// <typeparam name="T">The expected object type.</typeparam> internal static IReadOnlyList <T> MyFindAll <T>(this IObjectTreeNode source, ISearchPattern pattern, int depth = 1) where T : class, IObjectTreeNode { List <T> result = new List <T>(); Queue <Tuple <IObjectTreeNode, int> > q = new Queue <Tuple <IObjectTreeNode, int> >(); q.Enqueue(new Tuple <IObjectTreeNode, int>(source, 0)); while (q.Count > 0) { Tuple <IObjectTreeNode, int> current = q.Dequeue(); if (current == null) { continue; } if (current.Item2 != 0) { object value; if (pattern.GetPatternItems().All((i) => current.Item1.TryGetProperty(i.Key, out value) && i.Value.Equals(value))) { result.Add(current.Item1.Cast <T>()); continue; // do not further search on this path } } if (current.Item2 != depth) { foreach (IObjectTreeNode child in current.Item1.Children) { q.Enqueue(new Tuple <IObjectTreeNode, int>(child, current.Item2 + 1)); } } } return(result); }