2011-02-24 72 views

回答

10

你可以得到边界框使用TransformToVisual

因此,任何Visual,如果你有这样的

<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> 

定义的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,则边框会大很多又是什么画

<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
包围盒比较

+0

感谢您的回答。但是,正如你所说 - 我仍然无法获得正确的线条边界框。它确实适用于FrameworkElements,但不适用于Shapes。 – 2011-02-24 13:39:40

+0

将形状加载到画布时,我没有定义Canvas.SetLeft/SetRight。由于点数据的缘故,它会自动呈现正确位置的形状。这可能是问题吗? – 2011-02-24 14:27:16

+0

@Horse Pen:我不确定我是否明白'Line'是什么意思。你是否有任何错误,或者你是否得到了Bounding Box的“错误”值?在后一种情况下,我认为问题在于这实际上是边界框,Visual Studio Designer在选择它时显示相同的内容。为了得到实际的绘制边界,我能想到的唯一方法是从形状创建一个位图并逐步处理像素。 – 2011-02-24 14:31:30

4

我我也遇到了这个问题,并发现一种很好的方法来获取形状的边界框,如果有的话也包括笔划,并且几乎适用于我抛出的任何路径,它是VisualContentBounds属性来自WPF Visual类。问题在于它是内部的(使用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); 
    }