C# WPF:如何获得形状的真实大小(边界框)
我在获取形状的实际大小(边界框)时遇到问题 我尝试使用RenderSize和ActualSize,但它们返回的值没有意义。 但是,对UIElements使用这些方法非常有效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"
如果您能帮助我,我将不胜感激。您可以使用
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);
}