devios1
devios1

Reputation: 38025

Determine the bounding rect of a WPF element relative to some parent

I consider this a pretty simple request, but I can't seem to find a conclusive answer in my searches. How can I determine the bounds of a particular visual element in my window, relative to some other parent element?

I've tried using LayoutInformation.GetLayoutSlot but this just seems to return a Rect at 0,0 and doesn't reflect the actual location of the element.

What I'm trying to do is take a "screenshot" of a window using RenderTargetBitmap and then crop it to a particular element, but I can't get the element's bounds to know what to crop the bitmap to!

Upvotes: 20

Views: 18219

Answers (4)

Mauro Sampietro
Mauro Sampietro

Reputation: 2814

Taking into account a few suggestions i found here this solved the problem for me.

item.TransformToVisual( relativeToElement )
    .TransformBounds( new Rect( item.RenderSize ) );

Upvotes: 6

DanW
DanW

Reputation: 2056

The LayoutSlot option didn't work for me at all. This ended up giving me a child position relative to a specified parent/ancestor control:

    public static Rect BoundsRelativeTo(this FrameworkElement child, Visual parent)
    {
        GeneralTransform gt = child.TransformToAncestor(parent);
        return gt.TransformBounds(new Rect(0, 0, child.ActualWidth, child.ActualHeight));
    }

Upvotes: 9

Ray Burns
Ray Burns

Reputation: 62929

It is quite simple:

public static Rect BoundsRelativeTo(this FrameworkElement element,
                                         Visual relativeTo)
{
  return
    element.TransformToVisual(relativeTo)
           .TransformBounds(LayoutInformation.GetLayoutSlot(element));
}

In fact it may be overkill to put it in a separate method.

Upvotes: 21

devios1
devios1

Reputation: 38025

Nevermind, I finally managed to figure it out using a combination of LayoutInformation.GetLayoutSlot() (although I probably could have used either ActualWidth/ActualHeight or RenderSize) and UIElement.TranslatePoint().

Seems a rather complicated solution when it could be as simple as this:

myElement.GetBounds( relativeElement );

Oh well. Maybe time for an extension method. :)

Upvotes: 1

Related Questions