Repository: AvaloniaUI/Avalonia
File: src/Avalonia.Base/VisualTree/VisualExtensions.cs (C#)

Code before:
                yield return v;
                v = v.VisualParent;
            }
        }

        /// <summary>
        /// Finds first ancestor of given type.
        /// </summary>
        /// <typeparam name="T">Ancestor type.</typeparam>
        /// <param name="visual">The visual.</param>
        /// <param name="includeSelf">If given visual should be included in search.</param>
        /// <returns>First ancestor of given type.</returns>
        public static T? FindAncestorOfType<T>(this Visual? visual, bool includeSelf = false) where T : class
        {
            return FindAncestorOfType<T>(visual, includeSelf, predicate: null);
        }

        /// <summary>
        /// Finds first ancestor of given type that matches a predicate.
        /// </summary>
        /// <typeparam name="T">Ancestor type.</typeparam>
        /// <param name="visual">The visual.</param>
        /// <param name="includeSelf">If given visual should be included in search.</param>
        /// <param name="predicate">The predicate that the ancestor must match.</param>
        /// <returns>First ancestor of given type.</returns>
        public static T? FindAncestorOfType<T>(this Visual? visual, bool includeSelf, Func<Visual, bool>? predicate) where T : class
        {
            if (visual is null)
            {
                return null;
            }

            Visual? parent = includeSelf ? visual : visual.VisualParent;

            while (parent != null)
            {
                if (parent is T result)
                {
                    if (predicate == null || predicate(parent))
                    {
                        return result;
                    }
                }

                parent = parent.VisualParent;
            }

            return null;
        }

        /// <summary>

Review comment (suggestion):
Should `Predicate<Visual>?` be used instead?
https://learn.microsoft.com/en-us/dotnet/api/system.predicate-1?view=net-10.0

Code after:
                yield return v;
                v = v.VisualParent;
            }
        }

        /// <summary>
        /// Finds first ancestor of given type.
        /// </summary>
        /// <typeparam name="T">Ancestor type.</typeparam>
        /// <param name="visual">The visual.</param>
        /// <param name="includeSelf">If given visual should be included in search.</param>
        /// <returns>First ancestor of given type.</returns>
        public static T? FindAncestorOfType<T>(this Visual? visual, bool includeSelf = false) where T : class
        {
            return FindAncestorOfType<T>(visual, includeSelf, predicate: null);
        }

        /// <summary>
        /// Finds first ancestor of given type that matches a predicate.
        /// </summary>
        /// <typeparam name="T">Ancestor type.</typeparam>
        /// <param name="visual">The visual.</param>
        /// <param name="includeSelf">If given visual should be included in search.</param>
        /// <param name="predicate">The predicate that the ancestor must match.</param>
        /// <returns>First ancestor of given type.</returns>
        public static T? FindAncestorOfType<T>(this Visual? visual, bool includeSelf, Predicate<T>? predicate) where T : class
        {
            if (visual is null)
            {
                return null;
            }

            Visual? parent = includeSelf ? visual : visual.VisualParent;

            while (parent != null)
            {
                if (parent is T result)
                {
                    if (predicate == null || predicate(result))
                    {
                        return result;
                    }
                }

                parent = parent.VisualParent;
            }

            return null;
        }

        /// <summary>