static T?FindDescendantWithBreadthFirstSearch(DependencyObject element, ref TPredicate predicate)
            {
                // We're using a pooled buffer writer to amortize allocations for the temporary collection of children
                // to visit for each level. The underlying array is deliberately just of type object and not DependencyObject
                // to reduce the number of generic instantiations and allow the rented arrays to be reused more.
                using ArrayPoolBufferWriter <object> bufferWriter = ArrayPoolBufferWriter <object> .Create();

                int childrenCount = VisualTreeHelper.GetChildrenCount(element);

                // Add the top level children
                for (int i = 0; i < childrenCount; i++)
                {
                    DependencyObject child = VisualTreeHelper.GetChild(element, i);

                    if (child is T result && predicate.Match(result))
                    {
                        return(result);
                    }

                    bufferWriter.Add(child);
                }

                // Explore each depth level
                for (int i = 0; i < bufferWriter.Count; i++)
                {
                    DependencyObject parent = (DependencyObject)bufferWriter[i];

                    childrenCount = VisualTreeHelper.GetChildrenCount(parent);

                    for (int j = 0; j < childrenCount; j++)
                    {
                        DependencyObject child = VisualTreeHelper.GetChild(parent, j);

                        if (child is T result && predicate.Match(result))
                        {
                            return(result);
                        }

                        bufferWriter.Add(child);
                    }
                }

                return(null);
            }
예제 #2
0
 /// <summary cref="IEnumerator.MoveNext"/>
 public bool MoveNext()
 {
     while (enumerator.MoveNext())
     {
         if (predicate.Match(enumerator.Current))
         {
             return(true);
         }
     }
     return(false);
 }
            static T?FindDescendantWithDepthFirstSearch(DependencyObject element, ref TPredicate predicate)
            {
                int childrenCount = VisualTreeHelper.GetChildrenCount(element);

                for (int i = 0; i < childrenCount; i++)
                {
                    DependencyObject child = VisualTreeHelper.GetChild(element, i);

                    if (child is T result && predicate.Match(result))
                    {
                        return(result);
                    }

                    T?descendant = FindDescendantWithDepthFirstSearch(child, ref predicate);

                    if (descendant is not null)
                    {
                        return(descendant);
                    }
                }

                return(null);
            }