WPF:如何获得形状的真实大小(边界框)

时间:2011-02-24 12:16:52

标签: c# .net wpf

我在获取Shapes的实际大小(边界框)方面遇到了麻烦。

我尝试使用RenderSize和ActualSize但它们返回的值没有意义。 但是,对UIElements使用这些方法效果很好。

如果你可以帮助我,我会很有意思。

2 个答案:

答案 0 :(得分:10)

您可以使用Visual

获取任何TransformToVisual的边界框

因此,如果您有Polygon这样的定义

<Canvas Name="canvas">
    <Polygon Name="polygon" Canvas.Left="12" Canvas.Top="12"
             Points="0,75 100,0 100,150 0,75"
             Stroke="Purple"
             Fill="#9999ff"
             StrokeThickness="1"/>
</Canvas>

然后,您可以使用以下代码在其边界框周围添加Border

private void AddBorderForFrameworkElement(FrameworkElement element)
{
    Rect bounds = element.TransformToVisual(canvas).TransformBounds(new Rect(element.RenderSize));
    Border boundingBox = new Border { BorderBrush = Brushes.Red, BorderThickness = new Thickness(1) };
    Canvas.SetLeft(boundingBox, bounds.Left);
    Canvas.SetTop(boundingBox, bounds.Top);
    boundingBox.Width = bounds.Width;
    boundingBox.Height = bounds.Height;
    canvas.Children.Add(boundingBox);            
}

但是,使用此方法可能无法始终获得所需的结果,因为“边界框”并不总是实际绘制的边界。如果您改为定义Polygon,如下所示,您开始绘制x = 100的位置,那么边界框将比绘制的内容大得多

<Polygon Name="polygon" Canvas.Left="140" Canvas.Top="12"
         Points="100,75 200,0 200,150 100,75"
         Stroke="Purple"
         Fill="#9999ff"
         StrokeThickness="1"/>

enter image description here
边界框比较

答案 1 :(得分:4)

我也遇到过这个问题,并且找到了一个很好的方法来获取形状的精确边界框,如果有任何形状,也可以包含笔划,并且几乎任何我抛出的路径都适用于WPF Visual类的VisualContentBounds属性。这个问题是它的内部(用Reflector找到它),所以你只能将它用于内置的WPF形状(因为你不能在程序集之外覆盖它)而你需要得到它它通过反思:

    Rect visualContentBounds = (Rect)GetPrivatePropertyValue(myShape, "VisualContentBounds");

    /*...*/

    private static object GetPrivatePropertyValue(object obj, string propName)
    {
        if (obj == null)
            throw new ArgumentNullException("obj");

        Type t = obj.GetType();
        PropertyInfo pi = t.GetProperty(propName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);

        if (pi == null)
            throw new ArgumentOutOfRangeException("propName", string.Format("Field {0} was not found in Type {1}", propName, obj.GetType().FullName));

        return pi.GetValue(obj, null);
    }