static IEnumerable <IVisual> HitTest( IVisual visual, Point p, Func <IVisual, bool> filter) { Contract.Requires <ArgumentNullException>(visual != null); if (filter?.Invoke(visual) != false) { bool containsPoint = BoundsTracker.GetTransformedBounds((Visual)visual)?.Contains(p) == true; if ((containsPoint || !visual.ClipToBounds) && visual.VisualChildren.Count > 0) { foreach (var child in visual.VisualChildren.SortByZIndex()) { foreach (var result in HitTest(child, p, filter)) { yield return(result); } } } if (containsPoint) { yield return(visual); } } }
/// <summary> /// Returns the active input elements at a point on an <see cref="IInputElement"/>. /// </summary> /// <param name="element">The element to test.</param> /// <param name="p">The point on <paramref name="element"/>.</param> /// <returns> /// The active input elements found at the point, ordered topmost first. /// </returns> public static IEnumerable <IInputElement> GetInputElementsAt(this IInputElement element, Point p) { Contract.Requires <ArgumentNullException>(element != null); if (element.IsVisible && element.IsHitTestVisible && element.IsEnabledCore) { bool containsPoint = BoundsTracker.GetTransformedBounds((Visual)element).Contains(p); if ((containsPoint || !element.ClipToBounds) && element.VisualChildren.Any()) { foreach (var child in ZSort(element.VisualChildren.OfType <IInputElement>())) { foreach (var result in child.GetInputElementsAt(p)) { yield return(result); } } } if (containsPoint) { yield return(element); } } }
/// <summary> /// Determines whether the specified element is currently visible to the user. /// </summary> /// <param name="element">The element.</param> /// <returns><c>true</c> if if the specified element is currently visible to the user; otherwise, <c>false</c>.</returns> private static bool IsUserVisible(Control element) { return(element.IsEffectivelyVisible && BoundsTracker.GetTransformedBounds(element).HasValue); }