让文本与TextBlock的顶部齐平(不是VerticalAlignment,我保证!)

时间:2014-04-23 14:28:52

标签: c# wpf xaml fonts styles

我试图让文本与TextBlock的顶部齐平并没有成功,我总是留在文本上方几个像素的间隙。

字体越大,间隙越大,因此在12号字体大小上并不明显,但50的大小使其非常明显

链接到图片[http://i.stack.imgur.com/dJFVY.png]

产生此代码的代码示例是:

<TextBlock Background="LightCyan"
           VerticalAlignment="Top"
           FontSize="12"
           Text="The quick brown fox"/>

<TextBlock Background="Aqua"
           VerticalAlignment="Top"
           FontSize="50"
           Text="The quick brown fox"/>

<TextBlock Background="LightGray"
           VerticalAlignment="Top"
           FontSize="80"
           Text="The quick brown fox"/>

我也不认为它的Font本身有问题,因为photoshop(例如)渲染相同的字体与文本区域的顶部正确对齐。

是否有人对造成差距的原因以及如何删除它有任何想法?

以下是我尝试过的一些事情:

  1. 将VerticalAlignment设置为顶部

  2. LineStackingStrategy 设置为“ BlockLineHeight ”,并将 LineHeight 值设置为字体大小。 (虽然这似乎有很大帮助,但这会影响所有文本行(如果它是多行的)。我希望找到一个只能影响顶部空间的解决方案。)

  3. 在自定义类中呈现文本。 (我真的想避免这样做,因为我必须重新创建TextBlock的所有功能。)

  4. 修改

    以防万一其他人需要这个,有 BlueM NETscape 的帮助和这个非常方便的链接:TextBlock as big as a capital letter (ignoring font ascender/descender)其中有一个很酷的解决方案,我用他们所有的想法实现了这个:

    在我的代码隐藏中,我已经有了一个表示我的文本的对象(这是一个拖放式程序)。在它的构造函数中,我添加了以下代码:

      Typeface typeface = new Typeface(Font_Family, Font_Style, Font_Weight, new FontStretch());
      GlyphTypeface glyphTypeface;
    
      typeface.TryGetGlyphTypeface( out glyphTypeface );
    
      double baseline = glyphTypeface.Baseline * Font_Size;
      double capsHeight = glyphTypeface.CapsHeight Font_Size;
      double glyphOffset = -1 * (baseline - capsHeight);
    
      GlyphOffset = new Thickness(0, glyphOffset, 0, 0);
    

    (原谅缺乏错误检查)

    基线:字体“坐”的行。

    CapsHeight:大写字母的高度。

    上面的代码基本上会找到从文本块顶部到大写字母顶部的距离,然后创建一个具有该高度的厚度来偏移视图中的文本块。

    注意:我假设大写字母是最高的字符(这并非总是如此,但对我的目的而言足够好。你可以遍历文本中的所有字形并找到最高的字形)

    在我看来,然后我将TextBlock的边距绑定到GlyphOffset属性,它恰当地抵消了文本! (感谢NETscape,这个边缘技巧!)

1 个答案:

答案 0 :(得分:5)

这似乎是字体的属性。为了证明我试图将两种不同的字体放入Excel单元格(作为WPF中性)并查看边距是如何添加的。

结果如下:

enter image description here

正如您所看到的,Segoe UI增加了比相同字体大小的Tahoma更大的上边距。

Wikipedia将此描述为 ascender height

enter image description here

Microsoft描述了OpenType™高度属性here

enter image description here

所以,是的,它是该特定字体的内置属性。

编辑: 我尝试了不同的解决方案,并在TextBlock上将边距设置为负边距,只需按照您的要求工作并保留行高。

<TextBlock 
  Text="This is a test with wrap" 
  TextWrapping="Wrap" 
  FontFamily="SegoeUI" 
  FontSize="70" 
  Margin="0, -12, 0, 0"/>

enter image description here

您可以将Margin属性绑定到计算中,该计算使用所使用字体的字体指标使其工作在不同的大小。