This is an update to my Syntax Highlighting TextBox in Silverlight using MVVM post.
First of all, i’d like to thank Jeff Willcox for his port to Silverlight of Drew Miller’s syntax highlighting engine called ColorCode and Morten Nielsen for putting it together with my overlaying TextBox idea.
Morten’s SyntaxHighlightingTextBox control is just for demo (he mentions that a polished version will be included in their SDK), and the performance goes down when the text is bigger than just a few lines of code.
I rewrote the control in order to improve the performance – the goal was to get instant update when typing.
Changes:
Used a RichTextBox in the background instead of a TextBox. They both use Inlines for the content so the change is trivial, but from my observations the RichTextBox is faster, especially for scrolling.
Fixed a couple of bugs in the Colorizer.
Problem:
Syntax highlighting is done on the UI thread at every key press; refreshing the syntax caused the whole content do be cleared and rebuilt.
Solution:
Use in memory entities for formatting instead of updating the Inlines collection directly. This decouples the syntax highlighting code from the UI and also enables background processing. Also, it enables partial updating – basically updating only the Inlines that changed instead of clearing and reloading all the content for the RichTextBox. Even more, it is possible to update only the style (color) for existing Inlines if the text is the same.
Problem:
With the syntax highlighting in the background, the UI continues responsive, but typing takes place in the invisible overlaying TextBox and it is not visible until the syntax highlighting updates the background RichTextBox, and it is confusing for the user. (For big texts, the syntax highlighting can take seconds).
Solution:
Use a DiffTextBox as overlay. A DiffTextBox handles all key presses and updates a list of text transforms (insert, remove, move caret). Using that information, I can update rapidly the affected RichTextBox Inlines and get instant update for the background. The syntax highlighting can now be delayed so that it takes place after the user stops typing (configurable HighlightDelay).
There is still a limit of text size that the text box can handle – if the text is very big (dozens of pages), the Silverlight TextBox and RichTextBox slow down considerably. I’m thinking this could be fixed by managing “virtual pages” and loading only the current context (several pages) in the control so that it keeps being responsive.
You can see the control in action in this code sharing site I built: CodeReturn.com. You can upload code that you want to share and / or embed in your pages. The best part is that you can edit the code (and soon: post replies to other people’s code) directly in the page where it is embedded! You just need to login with any OpenID account!
Like this:
Also, you can grab the source code here: SyntaxHighlighting.zip (99.63 kb).

Is C# the only language supported?
If not, how do you change the language?
Scratch that, I figured it out.
This is just what I was looking for. However, I found a bug.
I use a button to render dynamic code to your control, and this works great. But as soon as I manually type something in the code then the next time I click my button the bug will show. What happens is that it looks okay, it’ll show the new code just fine, but the overlay keeps the old text, so selecting anything gives strange and very unwanted results.
Another bug is that it only works well with english keyboards, which I guess is because of the ASCII lookup in the code. I can still type with my swedish keyboard, but the layout is a mess. I can deal with that though, since most users of my app are american.
Hi Gerhard,
Thank you for your feedback!
I’ll try to reproduce the bug you reported and fix it.
About the keyboard – yes, it only works with English now. The problem is that Silverlight API gives you only the code for the key that was pressed, with no information about the selected language. One solution would be to have a keyboard language selection inside the application, but I’m not sure if it can be made to sync with the OS’ input language.
Could codereturn.com run live code as well like http://wonderfl.net/c/2pg0 if you use Mono.CSharp client side compiler like http://dl.dropbox.com/u/6589941/SLCSharpRepl/index.html?
Hi slyi,
Yes, compiling (and running) code is one of the functions I want to add – although I haven’t investigated Mono.CSharp yet. I was looking into compiling it on the server and then dynamically load the resulting assembly.
Hi Vlad,
We produce the only commercial Silverlight-based syntax highlighting code editor control (http://www.actiprosoftware.com/products/dotnet/silverlight/syntaxeditor) and had originally also looked into ways to harness RichTextBox like this. However what we ended up going with was a model where we have a completely custom control (doesn’t use TextBox/RichTextBox) and we virtualize the rendering of view lines to help with performance. A custom control really wasn’t possible until Silverlight 4 added the text input events to the framework. The custom control design has worked out very well for us since we also can support things like collapsed outlining node adornments, or any other adornments (squiggle lines, etc.) very easily.
Hi Bill,
I agree, for extra performance and adornments, a custom control will work better and it is the next logical step.
For this first version I tried to take advantage as much as possible of the (Rich)TextBox’s built in editing functionality and just add the syntax highlighting part (although, in the end, I did end up doing some keystroke-by-keystroke stuff anyway).
Hi Vlad,
this is a really cool control. Do you also thought about building a content assist/code completion functionality into your editor component? If you need support, I would like to help you out. Do you have a project page for your component?
Cheers,
Andy
Hi Andy,
Sorry for the late reply, I’ve been out of town.
Yes, I have various upgrades in mind for the control, but I’ve been busy with other projects
Getting it up on Codeplex (or something similar) sounds like a good idea, I’ll do that as soon as I can and let you know.
Thanks,
Vlad
This control is superb. However, i have a issue with this. Any help would be greatly appreciated.
When i use the below code to load by default in the editor & when I try to edit the code, the curser will be in highlighted in some other position making difficult to edit the code.
Sample code
string GetClassFile()
{
return @”using System;
using System.Collections.Generic;
//using System.Linq;
using System.Text;
//using System.Xml.Linq;
using Thinkflow.Engine.Entity;
namespace Thinkflow.ScriptEditor
{
public class ClassName:IActivityEvents
{
public void OnBeforeActivityExecution(ActionContext context)
{
throw new NotImplementedException();
}
public void OnAfterActivityExecution(ActionContext context)
{
throw new NotImplementedException();
}
public string Test(ActionContext context)
{
return context.ActivityName;
}
}
}”;
}
public SilverlightControl1()
{
InitializeComponent();
syntaxHighlightingTextBox1.SourceCode = GetClassFile();
}
Working as a Sr IT consultant
Still a problem.
When I trying to hit backspace in keyboard, it delete the content on other line. See this video: http://screencast.com/t/t0pyBEG1
I have the same problem. Do you know how to resolve it?
By chance is there an easy way to the read only and/or disabled style matching without too much trouble?
Hi
I’m a relative newbie to silverlight, loving this idea and have downloaded and built your source project, referenced inside a bare silverlight project and now… I’m a bit stuck.
I’m trying to dynamically create my page content, so instead of using the XAML I’m adding the controls via the c# code-behind.
I’m ‘using’ Codexcite.SyntaxHighlighting;
txtTextEdit = new Codexcite.SyntaxHighlighting.DiffTextBox();
txtTextEdit.Height = 130;
txtTextEdit.Tag = “editbox”;
txtTextEdit.Name = “editbox”;
grid.Children.Add(txtTextEdit);
What other additions would I need to get the syntax highlighting working (obviously choosing the correct language first)?
Apologies for being a bit stupid but… I’m being a bit stupid!
Yes this is what I was saying, Where is the new code, the coeltmpe code that uses the latest version of silverlight. I guess I can just cut and past the project files into a new project, But I thought that was part of updating. Maybe updating should also change the test page.