WPF: How to Get the True Size (Bounding Box) of Forms

I'm having trouble getting the actual size (bounding box) of the Shapes.

I tried to use RenderSize and ActualSize, but they return values ​​that do not make sense. However, using these methods for UIElements works fine.

If you can help me, I will be grateful.

+4
source share
2 answers

You can get a Bounding Box for any Visual with TransformToVisual

So, if you have Polygon defined as

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

You can then add a Border around your bounding box with the following code

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

However, you cannot always get the desired results using this, since the Bounding Box will not always be Bounds for what is actually drawn. If you instead define your Polygon , as shown below, where you start drawing, where x = 100, then the bounding box will be much larger than what is drawn

 <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
Comparative analysis of boxes

+10
source

I also ran into this problem and found that a good way to get an exact bounding box for shapes, one that includes a stroke, if any, and works for almost any path I chose for it, is the VisualContentBounds property from the class Visual WPF The problem is that it is internal (found it with Reflector), so you can only use it for WPF inline forms (since you cannot override it outside the assembly), and you need to get it through 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); } 
+4
source

Source: https://habr.com/ru/post/1341130/


All Articles