Why does this polyline not fit inside the ViewBox in WPF? - wpf

What I am trying to achieve is to fit the Polyline inside a Viewbox. I tried the Stretch options, however it does not seem to work with negative values. Can someone guide how to fit the content inside the ViewBox?
Following is my sample code:
<Viewbox Stretch="Uniform">
<Grid>
<Polyline Margin="10" Fill="Tan" HorizontalAlignment="Center"
VerticalAlignment="Center" Points="0,0 14,0 14,-38"
StrokeThickness="1" Stroke="Black"
RenderTransformOrigin="0.5,0.5">
<Polyline.RenderTransform>
<TransformGroup>
<RotateTransform Angle="180"/>
<ScaleTransform>
<ScaleTransform.ScaleX>-1</ScaleTransform.ScaleX>
</ScaleTransform>
</TransformGroup>
</Polyline.RenderTransform>
</Polyline>
</Grid>
</Viewbox>
The bounds go beyond the Viewbox, hence unable to get it to "fit" the view.

You shouldn't set the RenderTransform of an element in a Viewbox.
Instead of a Polyline you may use a Path with a polyline geometry, where you can set the Transform property of the Geometry object in the Path's Data:
<Viewbox Stretch="Uniform">
<Path Margin="10" Fill="Tan" StrokeThickness="1" Stroke="Black"
HorizontalAlignment="Center" VerticalAlignment="Center">
<Path.Data>
<PathGeometry Figures="M0,0 L14,0 14,-38">
<PathGeometry.Transform>
<TransformGroup>
<RotateTransform Angle="180"/>
<ScaleTransform>
<ScaleTransform.ScaleX>-1</ScaleTransform.ScaleX>
</ScaleTransform>
</TransformGroup>
</PathGeometry.Transform>
</PathGeometry>
</Path.Data>
</Path>
</Viewbox>
Edit: An alternative might be to set the LayoutTransform instead of RenderTransform. You would also have to set the Polyline's Stretch property:
<Viewbox>
<Polyline Margin="10" Fill="Tan" StrokeThickness="1" Stroke="Black"
Points="0,0 14,0 14,-38" Stretch="Uniform">
<Polyline.LayoutTransform>
<TransformGroup>
<RotateTransform Angle="180"/>
<ScaleTransform>
<ScaleTransform.ScaleX>-1</ScaleTransform.ScaleX>
</ScaleTransform>
</TransformGroup>
</Polyline.LayoutTransform>
</Polyline>
</Viewbox>

Related

WPF- Translate Transform changing the Y axis with

Im doing a image binding with a slider and the only thing that i want to do its move the Y axis down to up, but at this moment im moving the axis up to down. What can i do to invert the moving of the angle y?
This is the code:
<Image Margin="400,0,200,37" Source="/img/santa_claus.png" Stretch="Uniform" VerticalAlignment="Bottom" Width="200" Height="195">
<Image.RenderTransform>
<TranslateTransform Y="{Binding Value, ElementName=slider}" x:Name="transform"/>
</Image.RenderTransform>
</Image>
<Slider Minimum="1" Maximum="100" x:Name="slider" Height="40" RenderTransformOrigin="0.5,0.5" Margin="226,392,200,12" >
<Slider.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform AngleY="-0.584"/>
<RotateTransform/>
<TranslateTransform Y="-1.482"/>
</TransformGroup>
</Slider.RenderTransform>
</Slider>
I tryied diferent properties and changing the slider minimum to 100 and maximum to 1 but this nullifies the effect of the slider
You may invert the direction of the translation by two "mirroring" ScaleTransforms with ScaleY="-1".
<Image.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleY="-1"/>
<TranslateTransform Y="{Binding Value, ElementName=slider}"/>
<ScaleTransform ScaleY="-1"/>
</TransformGroup>
</Image.RenderTransform>
As a general note, do not use Margins for layout. Put the two elements in two rows of a Grid:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Image Grid.Row="0" Source="/img/santa_claus.png"
VerticalAlignment="Bottom" Stretch="Uniform" Width="200" Height="195">
<Image.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleY="-1"/>
<TranslateTransform Y="{Binding Value, ElementName=slider}"/>
<ScaleTransform ScaleY="-1"/>
</TransformGroup>
</Image.RenderTransform>
</Image>
<Slider Grid.Row="1" x:Name="slider"
Minimum="0" Maximum="100" Width="200" Margin="10"/>
</Grid>

How to add a border rectangle around image control in wpf?

I tried to add the wrapped the <Image with <border
I added
<Border BorderThickness="1">
And
</Border>
Then tried to wrapped the <Image like this :
<Border BorderThickness="1">
<Image x:Name="Img" HorizontalAlignment="Left" Height="233" Margin="467,54,0,0" VerticalAlignment="Top" Width="272" RenderTransformOrigin="0.5,0.5">
<Image.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform AngleY="0.704"/>
<RotateTransform/>
<TranslateTransform Y="0.614"/>
</TransformGroup>
</Image.RenderTransform>
</Image>
</Border>
But it does nothing when running the application.
In the designer on the main window I have a StackPanel and then on it the other controls also Image control.
I want to show the user that there is a Image control like pictureBox the problem is when running the program and the Image is still empty there is nothing that indicate that there is a Image control. That's why I want to draw a rectangle on the Image borders.
You need to pick a brush for your Border.
<Border BorderThickness="1" BorderBrush="Black">
<Image x:Name="Img" HorizontalAlignment="Left" Height="233" Margin="467,54,0,0" VerticalAlignment="Top" Width="272" RenderTransformOrigin="0.5,0.5">
<Image.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform AngleY="0.704"/>
<RotateTransform/>
<TranslateTransform Y="0.614"/>
</TransformGroup>
</Image.RenderTransform>
</Image>
</Border>
Actually, the method you applied is very close, since the picture will be in a border, it would be more logical to resize the border instead of resizing the picture. If you make an application like below, it will work for you.
<Border BorderThickness="2"
BorderBrush="Black"
VerticalAlignment="Center"
HorizontalAlignment="Center"
Height="128"
Width="128">
<Image HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Stretch="Fill"
Source="/Images/antenna.png"/>
</Border>
It will be enough to have something like this in your application.
<Border BorderThickness="3" BorderBrush="Red" Height="233" Width="272">
<Image x:Name="Img" HorizontalAlignment="Left" Margin="467,54,0,0" VerticalAlignment="Top" RenderTransformOrigin="0.5,0.5">
<Image.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform AngleY="0.704"/>
<RotateTransform/>
<TranslateTransform Y="0.614"/>
</TransformGroup>
</Image.RenderTransform>
</Image>
</Border>

Image control uses transformation differently than other controls?

Scratching my head. Why in the world do these controls appear at different locations? Here's my XAML:
First (black) rectangle is the reference rectangle.
Second (red) rectangle appears correctly centered on top of the reference rect.
The image control (gray) while having the same size and transform, appears slightly drifted.
<Canvas Width="800" Height="500">
<Rectangle Width="100" Height="100" Canvas.Left="300" Canvas.Top="200" Stroke="Black" />
<Rectangle Width="100" Height="100" Canvas.Left="300" Canvas.Top="200" Stroke="Red">
<Rectangle.RenderTransform>
<RotateTransform Angle="30" CenterX="50" CenterY="50" />
</Rectangle.RenderTransform>
</Rectangle>
<Image Width="100" Height="100" Canvas.Left="300" Canvas.Top="200">
<Image.RenderTransform>
<RotateTransform Angle="30" CenterX="50" CenterY="50" />
</Image.RenderTransform>
</Image>
</Canvas>
Appears like this in WPF designer:
As far as I'm concerned,the shape classed (like Rectangle) and Image may have diffrent behaviors for renderorigin,if you edit both values of Image rotatetransform centerX/Y to 0,they may behave the same
<Canvas Width="800" Height="500">
<Rectangle Width="100" Height="100" Canvas.Left="300" Canvas.Top="200 Stroke="Black" />
<Rectangle Width="100" Height="100" Canvas.Left="300" Canvas.Top="200" Stroke="Red">
<Rectangle.RenderTransform>
<RotateTransform Angle="30" CenterX="50" CenterY="50" />
</Rectangle.RenderTransform>
<Image Width="100" Height="100" Canvas.Left="300" Canvas.Top="200">
<Image.RenderTransform>
<RotateTransform Angle="30" CenterX="0" CenterY="0" />
</Image.RenderTransform>
</Image>

how "Stretch" property of Image in WPF Effects Transform?

how "Stretch" property of Image in WPF effects Transforms ?
I found that Stretch property of image effets the transforms applied to it.
When stretch=fill, then everything is fine but if stretch=uniform, the transforms are chaged.
I not getting why this happening. Plz explain.
CODE:
<Canvas Height="200" Width="200">
<Image Height="50" Width="50" RenderTransformOrigin="0.5,0.5" Source="Image.jpg" Stretch="Fill">
<Image.RenderTransform>
<TransformGroup>
<RotateTransform Angle="200" />
<TranslateTransform X="100" Y="100"/>
</TransformGroup>
</Image.RenderTransform>
</Image>
<Rectangle Height="50" Width="50" RenderTransformOrigin="0.5,0.5" Fill="RoyalBlue" Opacity="0.5">
<Rectangle.RenderTransform>
<TransformGroup>
<RotateTransform Angle="200" />
<TranslateTransform X="100" Y="100"/>
</TransformGroup>
</Image.RenderTransform>
</Rectangle>
</Canvas>
<Canvas Height="200" Width="200">
<Image Height="50" Width="50" RenderTransformOrigin="0.5,0.5" Source="Image.jpg" Stretch="Uniform">
<Image.RenderTransform>
<TransformGroup>
<RotateTransform Angle="200" />
<TranslateTransform X="100" Y="100"/>
</TransformGroup>
</Image.RenderTransform>
</Image>
<Rectangle Height="50" Width="50" RenderTransformOrigin="0.5,0.5" Fill="RoyalBlue" Opacity="0.5">
<Rectangle.RenderTransform>
<TransformGroup>
<RotateTransform Angle="200" />
<TranslateTransform X="100" Y="100"/>
</TransformGroup>
</Rectangle.RenderTransform>
</Rectangle>
</Canvas>
From my testing, it appears that this is just a bug in the way the Visual Studio designer previews this XAML.
I've taken your code and loaded it in both Visual Studio 2010 and in Expression Blend 4. In Visual Studio's designer, I see what you're talking about. In Expression Blend, the preview is correct.
Most importantly, when I run the application, it is rendered correctly. So I think you're ok. Just pretend like its not doing that or use Expression Blend when you have to work with this control.

WPF RotateTransform question on offset

In the following:
<Rectangle Height="60" HorizontalAlignment="Left" Margin="50,100,0,0" Name="rectangle2" Stroke="Black" VerticalAlignment="Top" Width="60" >
<Rectangle.RenderTransform>
<TransformGroup>
<RotateTransform Angle="45" CenterX="30" CenterY="30"/>
</TransformGroup>
</Rectangle.RenderTransform>
To rotate the rectangle on its centre I have to set the CenterX and Y to half of the Rectangle's size. Is there a way to do that in markup?
Something like CenterX="{Binding Path=Width\2}" ?
You can set RenderTrasformOrigin property on the Rectangle itself:
<Rectangle Height="60" HorizontalAlignment="Left" Margin="50,100,0,0" Name="rectangle2"
Stroke="Black" VerticalAlignment="Top" Width="60"
RenderTrasformOrigin="0.5,0.5">
<Rectangle.RenderTransform>
<TransformGroup>
<RotateTransform Angle="45" />
</TransformGroup>
</Rectangle.RenderTransform>

Resources