public void Should_Track_Bounds() { using (UnitTestApplication.Start(TestServices.StyledWindow)) { var target = new BoundsTracker(); var control = default(Rectangle); var tree = new Decorator { Padding = new Thickness(10), Child = new Decorator { Padding = new Thickness(5), Child = control = new Rectangle { Width = 15, Height = 15, }, } }; var context = new DrawingContext(Mock.Of<IDrawingContextImpl>()); tree.Measure(Size.Infinity); tree.Arrange(new Rect(0, 0, 100, 100)); context.Render(tree); var track = target.Track(control); var results = new List<TransformedBounds?>(); track.Subscribe(results.Add); Assert.Equal(new Rect(0, 0, 15, 15), results[0].Value.Bounds); Assert.Equal(Matrix.CreateTranslation(42, 42), results[0].Value.Transform); } }
/// <summary> /// Enumerates the visuals in the visual tree whose bounds contain a point. /// </summary> /// <param name="visual">The root visual to test.</param> /// <param name="p">The point.</param> /// <param name="filter"> /// A filter predicate. If the predicate returns false then the visual and all its /// children will be excluded from the results. /// </param> /// <returns>The visuals at the requested point.</returns> public static IEnumerable <IVisual> GetVisualsAt( this 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.Any()) { foreach (var child in visual.VisualChildren.SortByZIndex()) { foreach (var result in child.GetVisualsAt(p, filter)) { yield return(result); } } } if (containsPoint) { yield return(visual); } } }