I have some shapes described in XAML, mostly curved lines. Some of them have padding around the edges, achieved by placing them in a Canvas
larger than the shape. This Canvas
acts as a bounding box.
For example, this shape appears like this in Designer. The shape is the curved line. The outer square is the bounding Canvas
, indicated by red arrows.
<Canvas Height="160"
Width="160"
Background="Red">
<Path Stroke="#000000"
Data="M27.9,108 c0,0 25,-63 48.5,-51.5 s34.5,64.5 68.5,37">
</Path>
</Canvas>
Now I need to scale the Canvas
and its shape to dynamically fit a larger Canvas
, while maintaining the shape's Geometry
relative to its bounding Canvas
, and also while maintaining the Stroke.Thickness
.
This is how the shape appears without scaling (bounding Canvas
is red, Canvas
I need to scale to is yellow):
This how it needs to look after scaling, but without changing the Stroke.Thickness
. Here I'm using a ViewBox
:
Is there a solution to this problem that I am overlooking?
I suspect the only solution involves setting the shape's Path.Stretch
to Fill
, changing its Height
and Width
, and then applying a Margin
to the bounding Canvas
to replicate the padding, which sounds quite horrible.
You can simply set the Path.Stretch
property to Fill
and the geometry will automatically scale to the size of the shape. Unfortunately, when the geometry is stretched, it is also "trimmed" to a minimal bounding box, so you'll loose the margins around the geometry, but you can always set Path.Margin
to desired values. Also, you should drop the wrapping Canvas
altogether.
However, judging by the image with desired effect you also want the margin to scale together with the geometry itself. In this case setting Path.Margin
won't cut the mustard - the margins will remain "constant". Fortunately, there's a simple trick that will solve this problem - all you need to do is to incorporate the margins in the geometry itself. To do that, you simply need to add two "empty" moves to the geometry, which would define two opposite points of the desired bounding box. In your case, if you want the shape to be nominally of size 160x160, and scale automatically to fit the available space, all you need is this:
<Path Stroke="#000000"
Data="M0,0 M160,160 M27.9,108 c0,0 25,-63 48.5,-51.5 s34.5,64.5 68.5,37"
Stretch="Fill" />
Path
does not have a Background
property though, so you might want to wrap it with a Border
after all.