A Code Project Article Editor with Live Preview

By Nicholas Butler
A tool to help author articles at The Code Project.

Click image for full screenshot - 306 KB

Table of Contents

{ Automatically generated Table of Contents }


This is a short article about an HTML editor I assembled with special support for writing articles at The Code Project.


Office 2007 doesn't contain a version of Frontpage, which I used to use to write articles. I didn't want to install Frontpage 2003 over Office 2007 "just in case!" So, I had a look around for an HTML editor that can show a preview side-by-side with the raw HTML. Visual Studio was the best one I found, but the preview has to be below the HTML, which is not what I want on my widescreen monitors. So I decided to write one myself. Here it is and I hope you find it useful.

Note: As Derek Bartram pointed out in the message board below, Visual Studio 2008 can split the source and design views vertically. The setting is:

Tools | Options | HTML Designer | General | Split views vertically

Assembly Instructions

It's a basic Windows Forms application with Weifen Luo's DockPanel Suite [^], so you can arrange the panes just how you want them. The editor is part of #develop from the ic#code [^] people. I also used their #ziplib. The preview pane is a plain old WebBrowser control.

Using BobBuilder

Window Types

There are two types of windows in BobBuilder: editor and preview. You must have exactly one editor window open for each document, but you can have any number of preview windows open.

Editor Windows

The TextEditor control from #develop has lots of nice features, like undo/redo and syntax highlighting. It also has loads of options that I have surfaced in the Tools | Options dialog. I have added shortcuts for some HTML tags like <code> and <pre>, which are often found in articles at The Code Project. Also, when you are in an opening tag, pressing TAB will close the tag for you and put the caret in the middle.


To help prevent illegal HTML being rendered, there are a few "autocompleted" characters. Firstly, if you type a <, you will get <>. Then if you are inside a tag, the quote, ", and single quote, ', characters will double up.

Preview Windows

The preview windows update continuously while you use the editor. If you have a system sound set for the "Navigation Started" event, you might like to disable it! The preview windows attempt to remember their scroll positions at each update, but this is not possible if illegal HTML is rendered.


There are buttons for the standard formattings like bold and italic. There is also an Action to insert a clickety.

Table of Contents

There are a menu item and a toolstrip button to insert a Table of Contents. This command parses the HTML using Regexs for all <hN> tags and inserts anchors around them. It then adds unordered lists of links to make the table. If a table already exists, then it will be replaced. Otherwise, the new table is inserted at the current caret position.

Known Issues


Any relative hyperlinks, for example to anchors, do not work in the preview windows. This is because the HTML is passed to the WebBrowser controls using their DocumentText property. When this happens, the WebBrowser sets the URI to about:blank and things stop working...

However, before the HTML is passed to the WebBrowser control, it is modified a bit. Some JavaScript is added to help maintain the scroll position and a <base> tag is added to make any inline references work, such as images. You can always save the document and use Tools | External Browser to quickly check that your relative links are working.

Note: when you upload your article, the HTML will be put in one of the main directories, but all other files (images, ZIPs, ... ) will be put in a subdirectory named the same as the basename of the article. For example, BobBuilder.aspx is in /KB/cs/ and all other files are in /KB/cs/BobBuilder/. You might like to replicate this structure locally when you are writing your article.

Points of Interest

There are a couple of points to highlight:

Design Patterns

I implemented the MVC pattern, but with a twist: I used the Observer pattern with the views subscribing to the (Singleton) controller as publisher. When an action is initiated, a command is sent to the controller using a normal method call. The controller does its work, firing events to communicate with any participating views.

A neat feature of the .NET event implementation of Observer is that the subscribers can alter the EventArgs derived parameter, so passing information back to the publisher. This is demonstrated in the implementation of the CurrentDocument property:

partial class Controller
   public static Document CurrentDocument
         return Instance
            .ExecuteCore( null, new Command.GetCurrentDocument() )

Instance gets the Singleton instance and ExecuteCore is a member method which returns its Command parameter. For the GetCurrentDocument command, all ExecuteCore does is raise the static Execute event. All the views have subscribed to this event and, when the currently active view handles it, it fills in the Document property of the command with its own (the current) document. So, when the event returns after calling all the views in its invocation list, the Document property has been set by the current view and is returned to whoever needs it.

This pattern made life easier than having the controller maintain a collection of some view interface. Now this is all taken care of by the built-in event handling, while reducing the coupling between the controller and the views.


I could not find a .NET way to determine the right member of this enumeration for a given char. In the end, I wrote this snippet:

[System.Runtime.InteropServices.DllImport( "user32.dll" )]
static extern short VkKeyScan( char ch );
static Keys ConvertToKeys( char c )
   short vk = VkKeyScan( c );
   int key = vk & 0x00FF;
   int mod = vk & 0xFF00;
   int iKeys = ( mod << 8 ) | key;
   Keys eKeys = ( Keys ) iKeys;
   return eKeys;


This is a short list of possible future enhancements. Please leave a comment below if you have any opinions or ideas.

  • Spelling checker
  • More common formattings
  • Configurable shortcuts
  • Macro compiler
  • Remember toolstrip positions
  • Handle exceptions better



  • 2008 - 02 - 01: First version
  • 2008 - 02 - 01: Removed smileys
  • 2008 - 02 - 03: Added auto-generation of Table of Contents
  • 2008 - 02 - 07: Fixed auto-generation of Table of Contents
  • 2009 - 08 - 05: Fixed preview placement with new DOCTYPE in template


This article, along with any associated source code and files, is licensed under The Code Project Open License.


If you have any feedback, please feel free to CONTACT me.