Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# WPF:如何获得形状的真实大小(边界框)_C#_.net_Wpf - Fatal编程技术网

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

C# WPF:如何获得形状的真实大小(边界框),c#,.net,wpf,C#,.net,Wpf,我在获取形状的实际大小(边界框)时遇到问题 我尝试使用RenderSize和ActualSize,但它们返回的值没有意义。 但是,对UIElements使用这些方法非常有效 如果您能帮助我,我将不胜感激。您可以使用TransformToVisual获得任何Visual的边界框 所以如果你有一个多边形定义如下 <Canvas Name="canvas"> <Polygon Name="polygon" Canvas.Left="12" Canvas.Top="12"

我在获取形状的实际大小(边界框)时遇到问题

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


如果您能帮助我,我将不胜感激。

您可以使用
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>
但是,由于边界框并不总是实际绘制内容的边界,因此使用此选项可能不会始终获得所需的结果。如果您改为定义
多边形
,如下图所示,在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"/>



边界框比较

我也遇到了这个问题,发现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);
    }

谢谢你的回答。但是,正如您所提到的,我仍然无法获得直线的正确边界框。它确实适用于框架元素,但不适用于形状。它会根据点数据自动在正确的位置显示形状。这可能是问题所在吗?@Horse Pen:我不确定我是否理解你所说的
Line
是什么意思。是否有任何错误或边界框的“错误”值?在后一种情况下,我认为问题在于这实际上是边界框,VisualStudioDesigner在选择它时显示相同的内容。要获得实际绘制的边界,我能想到的唯一方法是从形状创建位图,并逐步通过像素。px=thisPath.Data.bounds.X;py=thisPath.Data.Bounds.Y;如果形状具有负坐标,则此方法中的边界框将截断负部分。据我所知,如果控件具有负坐标,这是唯一有效的解决方案。从-100,-100到100100的一行将在这里得到一个正确的边界框,但不会得到另一个答案。
    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);
    }