开发者

Getting the true visual bounding box of a WPF element?

开发者 https://www.devze.com 2023-02-13 06:53 出处:网络
For a simplified version of my problem, I would like to calculate the bounding box of a layout-transformed (possibly even render-transformed) shape, so that I can always fit a rectangle perfectly arou

For a simplified version of my problem, I would like to calculate the bounding box of a layout-transformed (possibly even render-transformed) shape, so that I can always fit a rectangle perfectly around the shape, no matter what its rotation or scale may be. If you can solve this, I will be happy.

The more complex problem is that of calculating the visual bounding box of any framework element. By 'visual bounding box' I mean the top-most visible pixel within the framework element determines the top-bound, the right-most visible pixel determines the right-bound, etc. If you can solve this, I will be even more happy.

I have tried playing with LayoutInformation.GetLayoutSlot(), but this did not work in the expected manner. The 'layout slot' was actually MUCH larger than the actual bounds. I also tried using VisualTreeHelper.Get开发者_StackOverflowDescendantBounds(), but because of the VisualParent of my test shape being protected I could not manage to access this property, and decided to check here before I go any further into it.

I hope that somebody can provide an easy way of getting the true visual bounding box of an element in WPF, that is calculated AFTER all transforms. If I have not made something clear in my question, please let me know.


private Rect GetRectOfObject(FrameworkElement _element)
{
    Rect rectangleBounds = _element.RenderTransform.TransformBounds(
        new Rect(_element.RenderSize);

    return rectangleBounds;
}

Maybe this will help out.


You will get good results with VisualTreeHelper.GetDescendantBounds() and you can use VisualTreeHelper.GetParent() to gain access to the otherwise protected VisualParent property. However what you probably want to do is call GetDescendantBounds on the shape itself, not its parent, because in spite of its name, the method returns the bounds of the parent and all of its decendants.


The problem is not easy, as a control may draw outside its bounds.

But if you assume this doesn't happen you can solve the problem by using parent.TranslatePoint(point_in_child_coord_system, child) to transform (0,0), (child.ActualWidth,0), (child.ActualWidth, child.ActualHeight) and (0,child.ActualHeight) to the parent coord system. Then sort the x and y coordinates of all points and use minimum and maximum values to find the bounding box.

Note: sorting is necessary because of possible child rotation.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号