Syntax Highlighting TextBoxes in WPF – A Sad Story

One of the big new features in VS 2010 is the WPF based editor. With it, you can build all sorts of cool stuff like control the visualization of XML doc comments, change how intellisense looks, even scale the size of text based on the location of the caret. Huzzah for the WPF Visual Studio editor!

However, as wicked awesome as the new editor is, AFAIK it’s not going to be released as a separate component. So while the PowerShell, Intellipad and other teams inside Microsoft can reuse the VS editor bits, nobody else can. So if you want to do something like embed a colorizing REPL in your WPF app, you’ll have to use something else.

I’ve thought about putting a WPF based UI on top of ipydbg (though now I’d probably use the new lightweight debugger instead). So I downloaded John’s repl-lib code to see how he was doing it. Turns out his REPL control is essentially a wrapper around WPF’s RichTextBox control. It works, but it seems kinda kludgy. For example, the RichTextBox supports bold, italics and underline hotkeys, so John’s REPL does too. Though it is possible to turn off these formatting commands, I decided to take a look at modifying how the plain-old TextBox renders. After all, WPF controls are supposed to be lookless, right?

Well, apparently not all the WPF controls are lookless. In particular to this post, the TextBox is definitely NOT lookless. It looks like the text editing capabilities of TextBox are provided by the Sys.Win.Documents.TextEditor class while the text rendering is provided by the Sys.Win.Controls.TextBoxView class. Both of those classes are internal, so don’t even think about trying to customize or reuse them.

The best (and I use that term loosely) way I found for customizing the TextBox rendering was a couple of articles on CodeProject by Ken Johnson. Ken’s CodeBox control inherits from TextBox and sets the Foreground and Background to transparent (to hide the result of TextBoxView) and then overloads OnRender to render the text with colorization. Rendering the text twice – once transparently and once correctly – seems like a better solution than using the RichTextBox, but it’s still pretty kludgy. (Note, I’m calling the TextBox design kludgy – Ken’s code is a pretty good work around).

So if you want a colorized text box in WPF, your choices are:

  • Build your own class that inherits from RichTextBox, disabling all the formatting commands and handling the TextChanged event to do colorization
  • Build your own class that inherits from TextBox, but set Foreground an Background colors to transparent and overload OnRender to do the visible text rendering.
  • Use a 3rd party control. The only one I found was the AqiStar TextBox. No idea how good it is, but they claim to be a true lookless control. Any other syntax highlighting WPF controls around that I don’t know about?

Comments:

Sorta related: my strategy for my Silverlight mimic of Intellipad is basically the same as Ken's transparent overlay, except I'm writing my own RichTextBlock on top of TextBlock, and then FixedWidthRichTextBox on top of RichTextBlock (using the overlaid transparent TextBox for text selection and caret placement).
Actipro have recently released a WPF SyntaxEditor: http://www.actiprosoftware.com/Products/DotNet/WPF/SyntaxEditor/Default.aspx
Microsoft is great at providing frameworks, but horrible at providing tools for their frameworks. For example, WCF has almost zero quality tools from MS to work with. The WF editor blows goats. They are trying to foster all this language development with M and the DLR and the .NET framework itself, yet they don't make it easy for anyone to do anything other than build a language. If you actually want to build your own tools that don't ship inside of VS, all you will get is a big fuck you. The Java community is light years ahead on this front...
SharpDevelop has a WPF based editor called AvalonEdit. http://wiki.sharpdevelop.net/Default.aspx?Page=AvalonEdit&AspxAutoDetectCookieSupport=1 Its still in development but the source is available from subversion and it was pretty easy to get built and working, including python highlighting. I have a basic Python console working using and and so far it is working very well.
Actipro has a WPF based Syntax editor. We are looking at it for simple Python scripts.
Mark, my understanding is that SharpDevelop is GPL licensed. Is AvalonEdit also GPL?