相对于其容器,在WPF中绘制带有倾斜角度的文本/文本块/标签/控件

4

我有一个动态大小的网格(Grid)。我想在里面绘制一个斜对角的TextBlock。我已经有了一个斜对角的Path,你可以设置LineGeometry进行动态调整。但是我找不到与此相关联的TextBlock。我是否遗漏了什么?

<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>

预览

在此输入图片描述

目标

这是我想要的,但是不设置绝对的RotateTransform

在此输入图片描述

两种解决方案的比较

红色前景是FrankM的解决方案,绿色前景是Henrik Hansen的解决方案。

https://imgur.com/a/92X0LXI

2个回答

7

每当 Grid 的大小发生变化时,您需要计算 TextBlock 的角度,例如使用转换器。

以下是一个示例:

<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>

转换器代码:

转换器代码:

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();
        }
    }
}

结果:

屏幕截图1

屏幕截图2


我以为你不需要额外的“转换器”。无论如何,还是谢谢! - Dominic Jonas
@DominicJonas 这可以通过类似的代码实现,但我认为该解决方案在 WPF 中是相当适当和惯用的。 - heltonbiker

1
你也可以将TextBlock放在ViewBox中。它也会缩放文本,但这可能不是理想的选择?
<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


“Angle(角度)”应该自动计算,如果父元素的大小改变,则这种方式无效。 - Dominic Jonas
@DominicJonas:当我的机器上大小改变时,它可以正常工作,ViewBox会调整角度-这就是添加它的目的 :-) - user1562155
我刚刚测试了一下,发现透视图也被额外扭曲了!如果你想要这种效果,那肯定是一个解决方案!请查看我的原始帖子进行直接比较。 - Dominic Jonas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接