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

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

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

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

您可以使用TransformToVisual获取任何Visual的Bounding Box

所以如果你有一个像这样定义的Polygon

    

然后,您可以使用以下代码在其边界框周围添加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的位置,那么边界框将比绘制的大得多

  

在此处输入图像描述
边界框比较

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

  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); }