Getting text to sit flush against the top of a TextBlock (Not VerticalAlignment, I promise!)

StackOverflow https://stackoverflow.com/questions/23247405

  •  08-07-2023
  •  | 
  •  

Pergunta

I am trying to get text to sit flush against the top of a TextBlock with no success, I am always left with a gap of a few pixels above the text.

The larger the font, the larger the gap, so its not really that noticeable on a font size of say, 12, but a size of 50 makes it very obvious

Link to image [http://i.stack.imgur.com/dJFVY.png]

A code example to produce this is:

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

I also don't think its the Font itself that has the issue, as photoshop (for example) renders the same font correctly aligned with the top of the text area.

Does anybody have any ideas on what is causing the gap, and how to remove it?

Here are some things I've tried:

  1. Setting the VerticalAlignment to Top

  2. Setting LineStackingStrategy to "BlockLineHeight" and setting the LineHeight value to that of the Font size. (While this seems to help a lot, this will affects all lines of text (if its multilined). I was hoping a solution could be found that only affects the space at the top.)

  3. Rendering text in a custom class. (I would really like to avoid doing this, as I'd have to recreate ALL the functionality of the TextBlock.)

EDIT:

Just in case anyone else out there needs this, with BlueM's and NETscape's help and this very handy link: TextBlock as big as a capital letter (ignoring font ascender/descender) where G. Sofien had a very cool solution, I implemented this using all their ideas:

In my code-behind I already had an object representing my text (it's for a drag-and-drop sort of program). In it's constructor I added this code:

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

(Pardon the lack of error checking)

Baseline: the line where the font "sits".

CapsHeight: the height of a capital letter.

The above code will basically find the distance from the top of the textblock to the top of capital glyph and then create a Thickness with that height to offset textblock in the view.

Note: I am making the assumption that capitals are the tallest characters (which is not always true, but good enough for my purposes. You could iterate through all the glyphs in your text and find the tallest one)

In my view, I then bind the margin of the TextBlock to the GlyphOffset property and it appropriately offsets the text! (Thanks NETscape, for that margin trick!)

Foi útil?

Solução

This seems to be a property of the font. To prove that I tried to put two different fonts into Excel cells (to be WPF neutral) and see how margins are added.

This is the result:

enter image description here

As you can see, Segoe UI adds a larger top margin than Tahoma of the same font size.

Wikipedia describes this as ascender height:

enter image description here

Microsoft describes the OpenType™ height properties here.

enter image description here

So, yes its a builtin property of that specific font.

Edit: I tried different solutions and setting the margin to negative margin on a TextBlock simply works and preserves the line height as you requested.

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

enter image description here

You could bind the Margin attribute to a calculation which uses the font metrics of the used font to make it work in different sizes.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top