WPF, TextBlock Rotation, Alignment Issues - wpf

I would like to rotate the TextBlock based on the text's center point [Horizontal and vertical). I have tried the following code. it is always taking topleft corner of the textblock. How to change it to center of the text itself.
<TextBlock Name="textBlock1" TextWrapping="Wrap" FontSize="25" Foreground="#FFF63AFF" FontWeight="Bold">
TextBlock
<TextBlock.RenderTransform>
<TransformGroup>
<RotateTransform Angle="45" />
</TransformGroup>
</TextBlock.RenderTransform>
</TextBlock>
Image Description: Textblock is part of canvas and textblock should rotate based on the intersection as shown in the image
I have tried HorizontalAlignment as well as VerticalAlignment too, actually it is taking parent's alignment details.
Do I need to get the actual width and actual height, then based on that details calculate the center point?

You need to use RenderTransformOrigin=".5,.5"
<Grid>
<TextBlock Name="textBlock1" RenderTransformOrigin=".5,.5" HorizontalAlignment="Center" VerticalAlignment="Center" TextWrapping="Wrap" FontSize="25" Foreground="#FFF63AFF" FontWeight="Bold">
TextBlock
<TextBlock.RenderTransform>
<TransformGroup>
<RotateTransform Angle="45" />
</TransformGroup>
</TextBlock.RenderTransform>
</TextBlock>
</Grid>
Output

add the proprety in textbox :
TextAlignment="Center"
this is for horizontal alignement

Related

Clipping rotated objects in WPF

I want to make a set of buttons with 90 degree rotated text. I created the layout I wanted but found when I attached it to a button the layout clipped according to the button's (unrotated) layout. I haven't been able to figure out what's going on, but I created a simplified case without a button. Here's my XAML:
<Border Height="100" Width="50" BorderThickness="1" BorderBrush="Black">
<TextBlock>This is a test</TextBlock>
</Border>
This produces a border with clipped text (as expected)
But if I rotate the text, resulting in this XAML:
<Border Height="100" Width="50" BorderThickness="1" BorderBrush="Black">
<TextBlock RenderTransformOrigin="0.5,0.5">
<TextBlock.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform Angle="90"/>
<TranslateTransform/>
</TransformGroup>
</TextBlock.RenderTransform>This is a test</TextBlock>
</Border>
the text still clips according to the ''width'' of the enclosing border, not the height.
I'm sure I could size the border to include the text and rotate the border instead, and likely I could do the same with the buttons I'm trying to create, but if I do I don't know that I'm not going to run into the same problem with whatever bounds the buttons, so I feel like I need to understand what I'm missing. Why would a rotated object be clipped as if it wasn't rotated?
Set the LayoutTransform property, instead of RenderTransform:
<Border Height="100" Width="50" BorderThickness="1" BorderBrush="Black">
<TextBlock Text="This is a test">
<TextBlock.LayoutTransform>
<RotateTransform Angle="90"/>
</TextBlock.LayoutTransform>
</TextBlock>
</Border>
If desired, also set HorizontalAlignment="Center" and VerticalAlignment="Center" on the TextBlock.

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>

Bind rotation of content to the rotation of ancestor

I want to create a control with customized content.
The text inside should be rotated in the opposite direction to always be displayed vertically. To do this I have to bind rotation angle of text to rotation angle of text ancestor. How to do it? Sorry for my English.
Something like this should work. The important thing is to invert the rotation direction by two mirror transforms, before and after the child element rotation.
<Grid Background="AliceBlue" Width="200" Height="200"
RenderTransformOrigin="0.5,0.5">
<Grid.RenderTransform>
<RotateTransform Angle="45"/>
</Grid.RenderTransform>
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center"
Text="Hello" RenderTransformOrigin="0.5,0.5">
<TextBlock.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="-1"/>
<RotateTransform Angle="{Binding RenderTransform.Angle,
RelativeSource={RelativeSource AncestorType=Panel}}"/>
<ScaleTransform ScaleX="-1"/>
</TransformGroup>
</TextBlock.RenderTransform>
</TextBlock>
</Grid>

Fit image to page and auto hide scrollbar

<ScrollViewer x:Name="imagescrollviewer" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
<!--<Viewbox>-->
<Image x:Name="im" Source="{Binding JpgImageSource}" RenderTransformOrigin="0.5,0.5" Stretch="Uniform">
<Image.RenderTransform>
<ScaleTransform ScaleX="{Binding Value,ElementName=scaleslider}" ScaleY="{Binding Value,ElementName=scaleslider}"/>
</Image.RenderTransform>
</Image>
<!--</Viewbox>-->
</ScrollViewer>
<Slider x:Name="scaleslider" Orientation="Vertical" Height="100" Margin="5" HorizontalAlignment="Center" Maximum="4" Minimum="0.2" Value="1"/>
The scrollbar doesn't adpat to the image size properly. When the image gets bigger, the scrollbar should be shorter and vice versa. Is there some way to figure out the problem?
How to know the slider value when the image is fit to the window?
I suppose you need to use LayoutTransform instead of RenderTransform. This blog post describes the difference very well.
<Image x:Name="im" Source="{Binding JpgImageSource}" >
<Image.LayoutTransform>
<ScaleTransform ScaleX="{Binding Value,ElementName=scaleslider}" ScaleY="{Binding Value,ElementName=scaleslider}"/>
</Image.LayoutTransform>
</Image>

WPF - drawing text onto a GridSplitter

I am declaring this Grid Splitter:
<GridSplitter HorizontalAlignment="Right" VerticalAlignment="Stretch" Grid.Column="1" Grid.RowSpan="1" Grid.Row="1" Width="5" Background="#FFBCBCBC" ResizeBehavior="PreviousAndNext">
</GridSplitter>
It is a vertical grid splitter and I want to draw some text using RotateTransform so the text runs from top to bottom. I am having trouble getting it to work.
This should render the text as rotated.
<TextBlock Text="Testing" HorizontalAlignment="Center" VerticalAlignment="Center" IsHitTestVisible="False">
<TextBlock.LayoutTransform>
<RotateTransform Angle="90" />
</TextBlock.LayoutTransform>
</TextBlock>
You would then need to include it after your GridSplitter in the same column. The IsHitTestVisible is just in case it interferes with the mouse.
EDIT: Just to be clear, this would be a child of the Grid, not the GridSplitter. It would simply render on top of the GridSplitter.

Resources