Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Stretching a XAML Path to fill its containing element

I have a ControlTemplate with some Paths in it. I would like the Paths to stretch and fill the control they are in, such as a Button. How can I do this?

What I have currently looks like this:

<ControlTemplate x:Key="SomeTemplate" TargetType="Button">
    <Canvas Background="AliceBlue">
        <Path Data="M 99.5,50 A 49.5,49.5 0 1 1 0.5,50 A 49.5,49.5 0 1 1 99.5,50 z"
            Fill="White" Stroke="Black" StrokeThickness="1" />
        <Path Data="M 15,50 C 17.5,22.5 47.5,22.5 50,50 C 52.5,77.5 82.5,77.5 85,50"
            Stroke="Black" StrokeThickness="1" />
    </Canvas>
</ControlTemplate>

...

<Button Template="{StaticResource SomeTemplate}" Height="120" Width="120" />

I am aware of ScaleTransform's StrechX and StretchY attributes, but they are only proportional scaling of the original Path's size.

Would I use a value converter? Or perhaps some form of relative binding to the parent's size?

like image 629
sourcenouveau Avatar asked Jul 16 '09 15:07

sourcenouveau


2 Answers

Throwing a ViewBox around the Canvas in your example should work.

like image 200
Bryan Anderson Avatar answered Sep 22 '22 21:09

Bryan Anderson


To stretch a Path use the Stretch property. It works just like image stretching - described here: https://msdn.microsoft.com/en-us/library/system.windows.media.stretch(v=vs.110).aspx (System.Windows.Media > Stretch Enumeration). In the case shown below, setting the value to Uniform will preserve the path width-height ratio filling the control which it occupies so that the whole path is visible.

<Path Stretch="Uniform" Data="..."/>

There is a side-effect: Stretching a Path this way will "normalize" its data i.e. even if the data would be written so that all the points are transformed from the origin [1], when stretch the transform is omitted [2] (hope i'm explaining this clearly).

You can use this to your advantage when having a messy object from Inkscape for example (not transformed to the origin) not worrying about the transformed data.

Stretch="none" (default) - same as not using this property. Notice the data not having single point in the origin

<Grid Width="200" Height="200">
  <TextBlock Text="(0,0)" />
  <TextBlock Text="(200,200)" VerticalAlignment="Bottom" HorizontalAlignment="Right"/>
  <Path Stroke="Blue" Stretch="None" Fill="Beige" Data="M 63,50 82,86 107,62 84,65 Z"/>
  <Rectangle Stroke="Red" StrokeThickness="1"/>
</Grid>

Stretch="Uniform"

<Grid Width="200" Height="200">
  <TextBlock Text="(0,0)" />
  <TextBlock Text="(200,200)" VerticalAlignment="Bottom" HorizontalAlignment="Right"/>
  <Path Stroke="Blue" Stretch="Uniform" Fill="Beige" Data="M 63,50 82,86 107,62 84,65 Z"/>
  <Rectangle Stroke="Red" StrokeThickness="1"/>
</Grid>
like image 37
q23main Avatar answered Sep 18 '22 21:09

q23main