Jeremy White
Jeremy White

Reputation: 901

How do I scale path geometry to fit a viewbox without scaling the line width?

I want to draw a user control with content displayed. Essentially I want a custom box around whatever the content is.

I want that box to scale, so I am using a viewbox. Unfortunately, the viewbox transforms the entire displayed control, not just the geometry of the box. This leads to the lines used for the border to be stretched.

Here is my control that I need to stretch the points in the vector path to fit the parent box. Here is what I want to scale to fill the parent box

Here is the undesirable result that I get.

enter image description here

Is there any good way to strech-to-fill the geometry while not scaling the line drawing thickness?

I realize I could to this a few other ways with such simple geometry, but in my actual application the path is much more complicated.

Here is my control code for those who are interested :

<UserControl.Template>
    <ControlTemplate TargetType="{x:Type UserControl}">
        <Grid>
            <Viewbox Stretch="Fill">
                <Canvas Name="svg2" Margin="0" Width="100" Height="63" >
                    <Path Fill="#FFFFFFFF" Stroke="#FF6800FF" StrokeThickness="4" StrokeStartLineCap="Flat" StrokeEndLineCap="Flat" StrokeLineJoin="Miter" StrokeMiterLimit="4" Name="rect2985" RenderTransformOrigin="0,0">
                        <Path.Data>
                            <PathGeometry FillRule="Nonzero" Figures="M 0,250 L 0,50 L 150,50 L 200,-0.96 L 250,50 L 400,50 L 400,250 L 0,250z">
                                <PathGeometry.Transform>
                                    <TransformGroup>
                                        <ScaleTransform ScaleX=".24" ScaleY=".23" />
                                    </TransformGroup>
                                </PathGeometry.Transform>
                            </PathGeometry>
                        </Path.Data>

                        <Path.RenderTransform>
                            <TransformGroup>
                                <TranslateTransform X="2.1" Y="3" />
                            </TransformGroup>
                        </Path.RenderTransform>
                    </Path>

                    <Grid Canvas.Top="17" Width="90" HorizontalAlignment="Center" Height="40" Canvas.Left="5">
                        <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" 
                                  VerticalAlignment="{TemplateBinding VerticalContentAlignment}"        
                                  SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                    </Grid>

                </Canvas>
            </Viewbox>
        </Grid>
    </ControlTemplate>
</UserControl.Template>

Upvotes: 3

Views: 2869

Answers (1)

Chris Kerekes
Chris Kerekes

Reputation: 1116

Remove the Viewbox and to split your "border" into fixed size, horizontally stretching, and vertically stretching parts as in the picture below:

Content Decorator

From here we can see that the column widths (from left to right) should be:

  1. Fixed
  2. Variable/Stretching
  3. Fixed
  4. Variable/Stretching
  5. Fixed

And the row heights (from top to bottom) should be:

  1. Fixed
  2. Variable/Stretching
  3. Fixed

From here you can then construct the xaml grid and place each part of your "border" onto the corresponding location. This way when the height of your control is changed only the vertical lines are stretched. Similarily when the width of the content changed only the horizontal lines will be stretched.

Upvotes: 3

Related Questions