【问题标题】:TextBlock as big as a capital letter (ignoring font ascender/descender)TextBlock 和大写字母一样大(忽略字体升序/降序)
【发布时间】:2013-04-09 03:49:02
【问题描述】:

我希望在TextBlock 上获得特定行为,以便其高度仅包括大写字母的高度(从基线到顶部减去“上升高度”)。请查看来自Wikipedia 的图像Sphinx 以了解我的意思。此外,下面的图片可能更能说明我所追求的。

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

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

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

【问题讨论】:

标签: c# wpf xaml


【解决方案1】:

你可以尝试使用 LineStackingStrategy="BlockLineHeight" 属性和 LineHeight 属性上的转换器和 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}}"/>

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

【讨论】:

    【解决方案2】:

    更新:

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

    您可以使用 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 绑定到容器元素,例如;

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

    它们可能会呈现您想要的效果?

    【讨论】:

    • 嗯...不是真的。我在您的第一个 XAML 中看不到任何影响。第二个有一个额外的“.Value”,但仍然没有这样做。不管怎么说,还是要谢谢你。我添加了新图像以进一步解释。我越来越接近使用自定义转换器和多重绑定来解决这个问题。虽然它并不漂亮。我正在寻找一个简单的解决方案。
    • 好吧,我尝试进行编辑,但它不让我保存说帖子不能包含该内容?这是一件没有解释的奇怪事情,但我认为你想要做的可能是使用 GlyphTypeFace 来找到你的 lineheight 值并在没有你的线间隙(领先)的情况下设置它,如果我现在有时间我会在以后进行更多研究我很好奇到,以前从来没有理由用这种方式弄乱字体。
    • 谢谢!毕竟我得到了我想要的工作方式。如果没有人提出解决方案作为练习,我将在几天后发布我自己的答案。
    • 是的,请发布您的结果,我一直在为使用 Marlett 字体的向上/向下箭头按钮寻找与此类似的内容
    猜你喜欢
    • 2021-03-20
    • 2021-01-29
    • 2016-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-20
    • 1970-01-01
    • 2018-01-14
    相关资源
    最近更新 更多