Skip to content


WPF RichTextBox Subscript and Superscript Without Font Restrictions

Introduction

One of the most bizarre limitation of the WPF RichTextBox is its hit and miss support for subscript and superscript in text. Although you can set the style quite easily using appropriate command, in order for this property to actually alter the appearance of the text the font needs to be OpenType, and come with a Subscript/Superscript variant, which the vast majority of fonts do not. Obviously in a control that’s designed for user input, restricting what fonts can be used in this way is far from ideal.

An Alternative Approach

Having spent some time poking around inside RichTextBox I would strongly recommend that you don’t. Seriously. The code may well make you physically sick. In the past I have tried to use TextRange.ApplyPropertyValue, which takes a normal DependencyProperty, to attach my own property to a piece of text. You’d imagine this would be pretty straightforward, especially as attaching properties to other types is a fairly fundamental part of WPF, but unfortunately there’s a particularly lovely piece of code that checks to see if the DependencyProperty is on a predefined “allowed” list, and thows an exception if it isn’t. While this chunk of code scuppered my ideas in the past, it did provide a useful place to look for an alternative way to create Subscript and Superscript text.

One of the properties that we are “allowed” to apply to text is Inline.BaselineAlignmentProperty which takes its values from the BaselineAlignment enumeration which includes the following values:

  • Top
    A baseline that is aligned to the upper edge of the containing box.
  • Center
    A baseline that is aligned to the center of the containing box.
  • Bottom
    A baseline that is aligned at the lower edge of the containing box.
  • Baseline
    A baseline that is aligned at the actual baseline of the containing box.
  • TextTop
    A baseline that is aligned at the upper edge of the text baseline.
  • TextBottom
    A baseline that is aligned at the lower edge of the text baseline.
  • Subscript
    A baseline that is aligned at the subscript position of the containing box.
  • Superscript
    A baseline that is aligned at the superscript position of the containing box.

Subscript and Superscript look exactly like what we want, and amazingly, they actually work :-) To demonstrate the technique I’ve created two simple extension methods that toggle either Sub or Superscript on the selected text:

/// <summary>
/// Toggle Superscript for the currently selected text in a RichTextBox. Does not require the font to be OpenType or have a Superscript font style.
/// 
/// Doesn't attempt to change/restore the size of the font, just moves the baseline.
/// </summary>
/// <param name="richTextBox">RichTextBox with selected text</param>
public static void ToggleSelectionSuperscript(this RichTextBox richTextBox)
{
    var currentAlignment = richTextBox.Selection.GetPropertyValue(Inline.BaselineAlignmentProperty);

    BaselineAlignment newAlignment = ((BaselineAlignment)currentAlignment == BaselineAlignment.Superscript) ? BaselineAlignment.Baseline : BaselineAlignment.Superscript;
    richTextBox.Selection.ApplyPropertyValue(Inline.BaselineAlignmentProperty, newAlignment);
}

The code checks the current value of the BaselineAlignmentProperty and toggles the value as appropriate. I’ve made no attempt to adjust font size, or do anything clever, so it does look a little goofy, but it proves the concept. The demo application also includes the XAML content of the RichTextBox document so you can see exactly what content it’s producing:

RichTextBoxSubSuperscriptScreenshot

And that’s that, hope it helps someone out :-) You can grab the sample demo from the link below:

RichTextBoxSubSuperscript.zip

Share:
  • Twitter
  • DotNetKicks
  • DotNetShoutout
  • Google Bookmarks
  • Digg
  • del.icio.us
  • Live
  • Technorati
  • StumbleUpon
  • email
  • Netvibes
  • Ping.fm
  • Print
  • Reddit

Technorati Tags: , , ,

Posted in WPF.

Tagged with , , , .