45

How can I set some text as subscript/superscript in FormattedText in WPF?

ardila
  • 1,277
  • 1
  • 13
  • 24
Firoz
  • 7,224
  • 10
  • 41
  • 56

8 Answers8

50

You use Typography.Variants:

<TextBlock>
    <Run>Normal Text</Run>
    <Run Typography.Variants="Superscript">Superscript Text</Run>
    <Run Typography.Variants="Subscript">Subscript Text</Run>
</TextBlock>
Reed Copsey
  • 554,122
  • 78
  • 1,158
  • 1,373
  • 2
    There are some known bugs with this, at least as of .Net 4.0: http://social.msdn.microsoft.com/Forums/en/wpf/thread/f375a41b-2c36-4e51-8f6b-7ed828431412. Don't know if it is fixed in .Net 4.5. – skybluecodeflier Mar 20 '12 at 17:35
  • if some one get this bug with Win7 look at this link to fix it support.microsoft.com/kb/2670838 – WiiMaxx Mar 07 '13 at 15:09
  • 6
    It should be noted that the default UI font for Windows (and WPF) supports neither subscripts nor superscripts prior to Windows 8. – Chris Kerekes Apr 05 '13 at 20:02
19

You can use something like <TextBlock>5x<Run BaselineAlignment="Superscript">4</Run> + 4</TextBlock>.

However, as far as I know, you will have to reduce the font-size yourself.

Matthias
  • 12,053
  • 4
  • 49
  • 91
18

It's interesting to note that for some characters (m2, m3, etc) a superscript is not needed, but the unicode character can be used. For example:

<Run Text=" m&#x00B3;" />

This would show m3.

Freek Sanders
  • 1,187
  • 10
  • 26
  • 3
    See wikipedia for a complete overview: https://en.wikipedia.org/wiki/Unicode_subscripts_and_superscripts – Wouter Apr 20 '20 at 14:53
12

I used a layout transform, because Typography.Variants often doesn't work:

<TextBlock Text="MyAmazingProduct"/>
 <TextBlock Text="TM">
  <TextBlock.LayoutTransform>
   <!-- Typography.Variants="Superscript" didn't work -->
   <TransformGroup>
    <ScaleTransform ScaleX=".75" ScaleY=".75"/>
    <TranslateTransform Y="-5"/>
   </TransformGroup>
  </TextBlock.LayoutTransform>
 </TextBlock>
<TextBlock Text="{Binding Path=Version, StringFormat={} v{0}}"/>

The advantage of using a LayoutTransform is that it is insensitive to the fontsize. If the fontsize is changed afterwards, this superscript works where explicit FontSize setting breaks.

Ramon de Klein
  • 5,172
  • 2
  • 41
  • 64
4

Typography.Variants works only for open type fonts. If you dont like your superscripts/subscripts going outside the height of actual text then you can use something like the following:

<StackPanel Orientation="Horizontal">
    <TextBlock FontSize="10" Margin="0,5,0,0">1</TextBlock>
    <TextBlock FontSize="30">H</TextBlock>
    <TextBlock FontSize="10" Margin="0,20,0,0">2</TextBlock>
</StackPanel>
Nitin Chaudhari
  • 1,497
  • 16
  • 39
3

I don't know if you need this to work with FormattedText specifically, or you mean derivations of Inline, but the following will work on Inlines, even if Typography.Variants="Superscript" fails to work.

TextRange selection = new TextRange(document.ContentStart, document.ContentEnd);
selection.ApplyPropertyValue(Inline.BaselineAlignmentProperty, BaselineAlignment.Superscript);

Hope it helps!

T. Webster
  • 9,605
  • 6
  • 67
  • 94
  • This fails miserably in my tests, based on RichTextBox and otherwise successful with bold, italic, underline, font family/color/size. I use the same .ApplyPropertyValue() with all of those. I useToggleButton's so I verify the alignment is set and remembered, but without visual effect. – person27 Oct 02 '17 at 19:32
2

This is the only thing that worked for me. It also gives you more control over the alignment and font size.

<TextBlock Grid.Row="17">
    3 x 3<Run FontSize="6pt" BaselineAlignment="TextTop">2</Run>)
</TextBlock>
MoMo
  • 8,149
  • 3
  • 35
  • 31
0

Setting for superscript works fine with the following code:

<TextBlock Text="(cm"  />
<TextBlock ><Span BaselineAlignment="Top" FontSize="8">2</Span></TextBlock>
<TextBlock Text=")" />

Setting the Baseallignment for subscript in the Span tag did not work for me. I tried the following code and it worked fine.

  <TextBlock Text="H"  />
  <TextBlock Text="2" Margin="-2,0,-2,0" TextBlock.LineHeight="3" >   
  <TextBlock Text="O" />
Ben
  • 51,770
  • 36
  • 127
  • 149
GCP
  • 9
  • 2