TextBlock和大写字母一样大(忽略字体ascender / descender)

时间:2012-03-20 10:50:47

标签: c# wpf xaml

我希望在TextBlock上获得特定行为,以便其高度仅包括大写字母的高度(从基线到顶部减去“上升高度”)。请参阅Wikipedia中的图片Sphinx,了解我的意思。此外,下面的图片可能更好地表明了我的目标。

Sample enter image description here

我不是专门寻找纯XAML解决方案(可能是不可能的)所以后面的C#代码(转换器)也没问题。

这是XamlPad中用于在上图中生成左A的XAML。

<TextBlock Text="A" Background="Aquamarine" FontSize="120" HorizontalAlignment="Center" VerticalAlignment="Center" />

2 个答案:

答案 0 :(得分:4)

你可以尝试在LineHeight属性上使用属性LineStackingStrategy =“BlockLineHeight”和转换器,在TextBlock的高度上使用转换器。 这是转换器的示例代码

// Height Converter
public class FontSizeToHeightConverter : IValueConverter
{
    public static double COEFF = 0.715;
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return (double)value * COEFF;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}
// LineHeightConverter
public class FontSizeToLineHeightConverter : IValueConverter
{
    public static double COEFF = 0.875;
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return double.Parse(value.ToString()) * COEFF;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

转换器上使用的系数取决于使用的系列字体(基线和行间距):

<TextBlock Text="ABC" Background="Aqua" LineStackingStrategy="BlockLineHeight" 
FontSize="{Binding ElementName=textBox1, Path=Text}" 
FontFamily="{Binding ElementName=listFonts, Path=SelectedItem}" 
Height="{Binding RelativeSource={RelativeSource Self}, Path=FontSize, Mode=OneWay, Converter={StaticResource FontSizeToHeightConverter1}}"
LineHeight="{Binding RelativeSource={RelativeSource Self}, Path=FontSize, Converter={StaticResource FontSizeToLineHeightConverter}}"/>

sample with params Coeff = 0.7

最佳解决方案是找到如何根据FontFamily的参数Baseline和LineSpacing计算Coeff。 在此示例(Segeo UI)中,Coeff of Height = 0.715,LineHeight = 0,875 * FontSize。

答案 1 :(得分:1)

更新:

如果我理解正确,我知道有一些技巧,

您可以使用RenderTransform Scale,这通常是最有效的方法;

<TextBlock Text="Blah">
  <TextBlock.RenderTransform>
   <CompositeTransform ScaleY="3"/>
  </TextBlock.RenderTransform>
</TextBlock>

或者您可以在TextBlock中嵌入Viewbox来“缩放”文本以适应其容器的边界,例如,您可以在网格行上设置硬高度值,例如;

<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="120"/>
<RowDefinition Height="120"/>
</Grid.RowDefinitions>
<Viewbox VerticalAlignment="Stretch" Height="Auto">
      <!-- The textblock and its contents are 
      stretched to fill its parent -->
      <TextBlock Text="Sphinx" />
</Viewbox>
<Viewbox Grid.Row="2" VerticalAlignment="Stretch" Height="Auto">
      <!-- The textblock and its contents are 
      stretched to fill its parent -->
      <TextBlock Text="Sphinx2" />
</Viewbox>

或者您可以将FontSize绑定到Container元素,例如;

<Grid x:Name="MyText" Height="120">
<TextBlock FontSize="{Binding ElementName=MyText, Path=Height}" Text="Sphinx" />
</Grid>

他们可能会表现出你想要的效果吗?