4

I have a Grid with a dynamic size. Inside I want to draw a diagonal TextBlock . I have already a diagonal Path where you can set LineGeometry for dynamic adjustment. But I can't find the pendant in the TextBlock. Do I miss something?

<Grid>
    <TextBlock Text="Draft" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="180" FontWeight="Bold" Foreground="#FFA43A3A" RenderTransformOrigin="0.5,0.5"/>
    <Path Grid.Row="2" Grid.Column="0" Stroke="Red" StrokeThickness="2" Stretch="Fill">
        <Path.Data>
            <LineGeometry StartPoint="1,0" EndPoint="0,1" />                
        </Path.Data>            
    </Path>
</Grid>

Preview

enter image description here

Target

This is waht I want to have without setting the absolute RotateTransform.

enter image description here

Comparism of both solutions

The red foreground is FrankM solution, the green one is from Henrik Hansen

https://i.stack.imgur.com/8X9Yb.jpg

Dominic Jonas
  • 4,717
  • 1
  • 34
  • 77

2 Answers2

7

You have to compute the angle of the TextBlock whenever the Grid's size changes, e.g. using a converter.

Here is an example:

<Window x:Class="WpfApplication13.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:WpfApplication13"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <local:AngleConverter x:Key="AngleConverter"/>
    </Window.Resources>
    <Grid x:Name="grid">
        <TextBlock Text="Draft" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="120" FontWeight="Bold" Foreground="#FFA43A3A"
                   RenderTransformOrigin="0.5,0.5">
            <TextBlock.RenderTransform>
                <MultiBinding Converter="{StaticResource AngleConverter}">
                    <MultiBinding.Bindings>
                        <Binding ElementName="grid" Path="ActualWidth"/>
                        <Binding ElementName="grid" Path="ActualHeight"/>
                    </MultiBinding.Bindings>
                </MultiBinding>
            </TextBlock.RenderTransform>
        </TextBlock>
        <Path Stroke="Red" StrokeThickness="2" Stretch="Fill">
            <Path.Data>
                <LineGeometry StartPoint="1,0" EndPoint="0,1" />
            </Path.Data>
        </Path>
    </Grid>
</Window>

The converter code:

using System;
using System.Globalization;
using System.Windows.Data;
using System.Windows.Media;

namespace WpfApplication13
{
    public class AngleConverter : IMultiValueConverter
    {
        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            double width = values[0] as double? ?? 0;
            double height = values[1] as double? ?? 0;

            double angleRadians = Math.Atan2(height, width);
            return new RotateTransform {Angle = - angleRadians * 180.0 / Math.PI};
        }

        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
}

Result:

Screenshot 1

Screenshot 2

FrankM
  • 1,007
  • 6
  • 15
1

You could also wrap the TextBlock in a ViewBox. It will scale the text too, but that may be undesirable?:

<Viewbox Stretch="Fill" StretchDirection="Both">
  <TextBlock Text="Draft" FontWeight="Bold" Foreground="#FFA43A3A" Margin="5" RenderTransformOrigin="0.5,0.5" >
    <TextBlock.RenderTransform>
      <RotateTransform Angle="-35.0" />
    </TextBlock.RenderTransform>
  </TextBlock>
</Viewbox>

enter image description here enter image description here

  • The `Angle` should be calculated automatically, this won't work if the size of the parent changes.. – Dominic Jonas Jun 27 '18 at 18:38
  • @DominicJonas: It works all right when size changes on my machine, the ViewBox adjust the angle - that's the point of adding the it :-) –  Jun 27 '18 at 19:01
  • I have just tested it and found that while the perspective is additionally distorted! If you want this effect, it is certainly a solution! See my original post for a direct comparism. – Dominic Jonas Jun 28 '18 at 06:15