Rotate border from bottom - wpf

I want to rotate a border But the rotation is done from the middle of the border, I want the rotation to be done from the end of the border just like a clock that rotates around a circle
this is my codes:
<ed:Arc
StartAngle="0" EndAngle="360" Stretch="None"
Height="300" Width="300" StrokeThickness="20"
StrokeDashArray=".25" Stroke="Turquoise"/>
<Border HorizontalAlignment="Center" CornerRadius="100,100,0,0" RenderTransformOrigin="0,0.5" Height="140" Width="2" BorderBrush="Red" BorderThickness="2">
<Border.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform Angle="40"/>
<TranslateTransform/>
</TransformGroup>
</Border.RenderTransform>
</Border>

Upper left corner:
<Border ....
RenderTransformOrigin="0,0">
<Border.RenderTransform>
<RotateTransform Angle="40"/>
</TextBox.RenderTransform>
</TextBox>
A couple more examples:
Bottom right corner - RenderTransformOrigin="1,1"
Middle of the bottom side - RenderTransformOrigin="0.5,1"

When you are creating drawings, it is often useful to use a Canvas and position child elements by means of the Canvas.Left and Canvas.Top properties.
Thus you would not have to deal with any offsets when you want to transform the elements. The element transforms could be calculated in their "local" coordinate system, like the one of the "clock hand" Line element in the example below, which goes from (0,0) to (0,-140) in the 12 o'clock position.
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Canvas Width="300" Height="300">
<Ellipse Width="300" Height="300" Stroke="Turquoise"
StrokeThickness="20" StrokeDashArray=".25"/>
<Line Canvas.Left="150" Canvas.Top="150"
Y2="-140" Stroke="Red" StrokeThickness="2" >
<Line.RenderTransform>
<RotateTransform Angle="{Binding Value,
ElementName=angleSlider}"/>
</Line.RenderTransform>
</Line>
</Canvas>
<Slider x:Name="angleSlider" Grid.Row="1" Width="200" Maximum="360"/>
</Grid>

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 translate objects with different parent together wpf Canvas and Grid

I'm trying to do a Rotate/Translate/Scale of objects using a canvas for the actual figure and I use a Grid for "thumbs" container (Thumbs are some small ellipses)
I have some trouble understanding the logic behind this example.
<Window x:Class="RotateMe.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:RotateMe"
mc:Ignorable="d"
Title="MainWindow" Height="300" Width="300">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="50"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Button x:Name="AddRectangle" Width="50" Grid.Row="0" HorizontalAlignment="Left" Click="AddRectangle_Click"/>
<Canvas x:Name="DrawingCanvas" Grid.Row="1" Background="Gray">
<Ellipse x:Name="Thumb3" Fill="Azure" Height="10" Width="10" >
<Ellipse.RenderTransform>
<TranslateTransform X="-50" Y="-50"/>
</Ellipse.RenderTransform>
</Ellipse>
<Ellipse x:Name="Thumb4" Fill="Beige" Height="10" Width="10" >
<Ellipse.RenderTransform>
<TranslateTransform X="50" Y="50"/>
</Ellipse.RenderTransform>
</Ellipse>
</Canvas>
<Grid x:Name="ThumbsParent" Grid.Row="1" RenderTransformOrigin="1,1">
<Ellipse x:Name="Thumb" Fill="Red" Height="10" Width="10" RenderTransformOrigin="1,1">
<Ellipse.RenderTransform>
<TranslateTransform X="-50" Y="-50"/>
</Ellipse.RenderTransform>
</Ellipse>
<Ellipse x:Name="Thumb2" Height="10" Width="10" Fill="Green">
<Ellipse.RenderTransform>
<TranslateTransform X="50" Y="50"/>
</Ellipse.RenderTransform>
</Ellipse>
</Grid>
</Grid>
</Window>
So here I have
A Grid over an Canvas (same size)
Each of them contain a 10/10 ellipse that one is render transform -50/-50 and one is 50/50.
I would have expected the same behavior (overlap of the ellipses on both -50/-50 and 50/50)
Instead it looks like this.
So from what I understand from this.
Grid renders from CenterX/CenterY
Canvas renders from 0/0.
Is there a particular reason this is happening?
Why I am asking this, because I wanted to use a TranslateTransform for all my object and if one moves, all should move, but because one translate from 0/0 and one from CenterX/CenterY the same translate won't work on these elements.

How to rotate an image inside ScrollViewer? [duplicate]

This question already has answers here:
WPF Clipping Problem
(2 answers)
Closed 5 years ago.
I try to rotate an image in a ScrollViewer (WPF), but the entire image needs to remain visible. The corners of the image are cut off, if rotation angle is for example 45. I tried setting the Width and Height of the image by calculation the surrounding rectangle of the rotated image. It works, but not if the rotation angle is over 45.
<Grid>
<ScrollViewer ScrollViewer.HorizontalScrollBarVisibility="Visible" Margin="0,0,0,0">
<Image x:Name="image" RenderTransformOrigin="0.5,0.5" Margin="0,0,0,0" MouseDown="image_MouseDown" MouseRightButtonDown="image_MouseRightButtonDown" MouseLeftButtonDown="image_MouseLeftButtonDown">
<Image.RenderTransform>
<TransformGroup>
<ScaleTransform x:Name="scal"/>
<SkewTransform/>
<RotateTransform Angle="90" x:Name="rot"/>
<TranslateTransform/>
</TransformGroup>
</Image.RenderTransform>
</Image>
</ScrollViewer>
</Grid>
Use a ViewBox in the following structure:
<ScrollViewer Width="100" Height="100" Background="Black" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto">
<Viewbox Width="100" Height="100">
<Border Width="100" Height="100" Background="Red" >
<Border.LayoutTransform>
<RotateTransform Angle="30" />
</Border.LayoutTransform>
</Border>
</Viewbox>
</ScrollViewer>
Note that you should set the size of the ViewBox and the inner Control (in your case the Image) equal to the size of the ScrollViewer. The ViewBox will adjust the size of the inner Control, in such a way that the ScrollBars are never Visible.
Note that I used a red Border, you can add the image.
Edit
Just checked it. You do not need to set the Widths, but just the size of inner Control. In other words, this works too:
<ScrollViewer Background="Black" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto">
<Viewbox>
<Border Width="1" Height="1" Background="Red" >
<Border.LayoutTransform>
<RotateTransform Angle="30" />
</Border.LayoutTransform>
</Border>
</Viewbox>
</ScrollViewer>

Change controls zero point in canvas

When i draw items in canvas, the position is take from top of the item inside canvas:
<Canvas Name="cnvMain"
Width="80"
Height="80">
<Ellipse Canvas.Top="20"
Canvas.Left="40"
Width="40"
Height="40"
Fill="Gray" />
</Canvas>
Now what i would need is to take the measurement from the bottom of the element, like this:
In the end i would like to be able to set the distance from the bottom of the Ellipse to the top of the Canvas.
NB: Ellipse can sometimes not be a circle and flipping it upside down is not an option. Also i dont know the height before runtime so setting negative margin in xaml will not work also.
(Picture and example xaml taken from: http://weblogs.asp.net/psheriff/centering-text-within-a-wpf-shape-using-a-canvas)
If you want to specify the distance of the bottom of the Ellipse to the bottom of the Canvas, you could replace Canvas.Top by Canvas.Bottom:
<Ellipse Canvas.Bottom="20" Canvas.Left="40" Width="40" Height="40" Fill="Gray"/>
For the distance from the bottom of the Ellipse to the top of the Canvas, you may specify a negative Margin:
<Ellipse Canvas.Top="20" Canvas.Left="40" Width="40" Height="40" Fill="Gray"
Margin="0,-40,0,0"/>
or an appropriate RenderTransform:
<Ellipse Canvas.Top="20" Canvas.Left="40" Width="40" Height="40" Fill="Gray">
<Ellipse.RenderTransform>
<ScaleTransform ScaleY="-1"/>
</Ellipse.RenderTransform>
</Ellipse>
In order to invert the y direction of the whole Canvas coordinate system, you may apply a RenderTransform to the Canvas:
<Canvas ... RenderTransformOrigin="0,0.5">
<Canvas.RenderTransform>
<ScaleTransform ScaleY="-1"/>
</Canvas.RenderTransform>
...
</Canvas>
Edit: You may also put the Ellipse in another Canvas with zero Height, and attach it to the lower Canvas border:
<Canvas Canvas.Top="20" Canvas.Left="40" Width="0" Height="0">
<Ellipse Canvas.Bottom="0" Width="40" Height="40" Fill="Gray"/>
</Canvas>

WPF Scaling Issue

I am perplexed with an issue that I am experiencing, using ScaleTransform. I have a Grid with a fixed width and height. The grid contains one child, a Rectangle. The Rectangle's Fill is a VisualBrush whose Visual binds to a canvas outside of the grid, whose dimensions are rather large. On the rectangle, I use a ScaleTransform, with ScaleX and ScaleY both being set to 0.18. Essentially, I am trying to scale the Rectangle's visual down to fit within my grid. What appears to be happening is that the Grid itself is being scaled down, resulting in a much smaller result than what I want. I have included the code below. Just as a point of reference, the height and width that the rectangle binds do are essentially 900 by 600, respectively. Any pointers as to what I might be doing wrong would be greatly appreciated.
<Grid Height="225" Width="200" Grid.Row="0" HorizontalAlignment="Left" VerticalAlignment="Top" x:Name="PART_Content">
<Rectangle Height="{Binding Path=ActualHeight}" Width="{Binding Path=ActualWidth}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Rectangle.Fill>
<VisualBrush Visual="{Binding}"/>
</Rectangle.Fill>
<Rectangle.RenderTransform>
<ScaleTransform ScaleX="0.183" ScaleY="0.183"/>
</Rectangle.RenderTransform>
</Rectangle>
</Grid>
Can you post the XAML for the Canvas element? I tried the following and I am getting the behavior you are going for (the rectangle is scaled and the grid is sized correctly)
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid ShowGridLines="True" Height="225" Width="200" Grid.Row="0" HorizontalAlignment="Left" VerticalAlignment="Top" x:Name="PART_Content">
<Rectangle Height="{Binding Path=ActualHeight}" Width="{Binding Path=ActualWidth}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Rectangle.Fill>
<VisualBrush Visual="{Binding ElementName=theCanvas}"/>
</Rectangle.Fill>
<Rectangle.RenderTransform>
<ScaleTransform ScaleX="0.183" ScaleY="0.183"/>
</Rectangle.RenderTransform>
</Rectangle>
</Grid>
<Canvas x:Name="theCanvas" Grid.Row="1">
<Rectangle Fill="Brown" Height="300" Width="300" />
</Canvas>
</Grid>
What is ActualWidth and ActualHeight? Unless I am mistaken the ActualHeight and ActualWidth properties as they normally mean in WPF are not DP's and you cannot bind to them. As has been pointed out below these are readonly dependency properties. Assuming this is in a CustomControl style Binding should be changed to TemplateBinding first.
I removed the bindings and essentially created a static version of your XAML which looks just fine. Since you have Part_Content defined for the grid, I am curious, is this xaml part of a custom control style? Is the code of the CustomControl manipulating the grid via PART_Content?
<Grid Height="225" Width="200" Grid.Row="0" HorizontalAlignment="Left" VerticalAlignment="Top" x:Name="PART_Content" Background="Red">
<Rectangle Height="225"
Width="200"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Fill="Blue">
<Rectangle.RenderTransform>
<ScaleTransform ScaleX="0.183" ScaleY="0.183"/>
</Rectangle.RenderTransform>
</Rectangle>
</Grid>

Resources