• Products
  • Download
  • Purchase
  • Support
  • Company
Actipro Software company logo
Twitter Follow Actipro RSS Subscribe (RSS Feed)

The Actipro Blog

Tag Cloud

  • aero
  • blog
  • docking
  • editors
  • gauge
  • intelliprompt
  • navigation
  • propertygrid
  • ribbon
  • shared library
  • silverlight
  • syntaxeditor
  • themes
  • views
  • winforms
  • wpf

Latest Twitter News

November 21, 2011 at 11:14 AM
#WPF Studio 2011.2 is out now! Includes enhanced themes for native WPF conrtols and new SyntaxEditor features. http://t.co/uEMCaGPG

September 26, 2011 at 1:25 PM
If you'd like to see our #WPF / #Silverlight SyntaxEditor code editor control ported to Metro, provide feedback here: http://t.co/xXBNIDTi

September 15, 2011 at 8:31 PM
If you want to see SyntaxEditor eventually show up in Win8's #xaml UI, be sure to add your support to this MS thread: http://t.co/FBjz6TuC

August 15, 2011 at 1:47 PM
New SyntaxEditor IntelliPrompt parameter info feature docs/samples ready for the 2011.2 #WPF and #Silverlight releases. http://t.co/ezoYIjv

August 2, 2011 at 2:40 PM
First look at new automated IntelliPrompt parameter info coming to our C#/VB editor control in #WPF / #Silverlight http://t.co/CUz6O1T

Twitter Follow us on Twitter

Month List

  • 2012
    • February (3)
    • January (2)
  • 2011
    • December (2)
    • November (7)
    • October (2)
    • September (1)
    • August (5)
    • July (3)
    • June (6)
    • May (5)
    • April (8)
    • March (4)
    • February (5)
    • January (9)
  • 2010
    • December (9)
    • November (10)
    • October (4)
    • September (8)
    • August (12)
    • July (9)
    • June (7)
    • May (6)
    • April (7)
    • March (6)
    • February (6)
    • January (4)
  • 2009
    • December (2)
    • November (2)
    • October (12)
    • September (3)
    • August (11)
    • July (10)
    • June (6)
    • May (3)
    • April (7)
    • March (6)
    • February (8)
    • January (10)
  • 2008
    • December (10)
    • November (2)
    • October (3)
    • September (5)
    • August (5)
    • July (8)
    • June (4)
    • May (4)
    • April (10)
    • March (8)
    • February (1)
    • January (2)

Category List

  • RSS feed for ActiproActipro (289)
  • RSS feed for Blog SummaryBlog Summary (13)
  • RSS feed for GeneralGeneral (34)
  • RSS feed for In developmentIn development (150)
  • RSS feed for New featuresNew features (140)
  • RSS feed for New productNew product (30)
  • RSS feed for PromotionPromotion (2)
  • RSS feed for SilverlightSilverlight (71)
  • RSS feed for Tips and tricksTips and tricks (4)
  • RSS feed for Visual Studio 2008Visual Studio 2008 (2)
  • RSS feed for Windows FormsWindows Forms (20)
  • RSS feed for Windows VistaWindows Vista (10)
  • RSS feed for WPFWPF (235)
  • RSS feed for XAMLXAML (23)

About Us

Actipro Software is a leading provider of .NET user interface controls for the WPF, Silverlight, and WinForms frameworks, and is most well-known for their SyntaxEditor syntax-highlighting code editor control.

Please take some time to learn more about us and our product offerings.

SyntaxEditor for WPF - Highlighting style configuration part 2

March 26, 2009 at 1:56 AM
by Bill Henning (Actipro)

Thanks for your comments on this post and via email on yesterday’s post about getting input on highlighting style configuration.  After reviewing your comments and talking things over internally here, I believe we have a simpler yet very robust way of both registering classification types and how they map to highlighting styles.

In today’s blog post I’d like to follow up on the conversation yesterday. 

Quick summary

Let me start off by summarizing the process of how text gets highlighted for display in a SyntaxEditor.

When a SyntaxEditor needs to draw text, it asks one or more active IClassifier instances to return logical classified spans of text.  The IClassifier defined by a syntax language essentially does some lexical parsing to create tokens, then takes those tokens and returns a IClassificationRange objects for the requested text range.  Again, a sample:

   1: int foo;

If a SyntaxEditor was drawing text for this line, it would first ask for the classification of the text on the line.  The current language’s IClassifier would be called, would tokenize the line, and return a classification result that says text range 0-3 is an IClassificationType with a Key of Keyword.  Then it would do the same thing for the tokens that follow, classifying them properly.

As an interesting side note, SyntaxEditor allows other layers of classifiers to be added in here.  This means you can classify a range as something else on the fly before SyntaxEditor gets the classification results.  Neat stuff!  :)  This feature is described in this blog post from January.

Next, the classification results use an IHighlightingStyleRegistry to map an IClassificationType to an IHighlightingStyle.  Thus each classified range gets a certain style applied to it and it renders with various colors, etc.  SyntaxEditor renders the text in the appropriate style, and voila, we have syntax highlighting.

Solution to yesterday’s post

Ok so that’s the summary, let’s dive into what we changed after yesterday’s post.  In our samples, we are making a getting-started series of QuickStarts that show the implementation of a programmatic lexing Simple language.  Full source included, of course. 

For our Simple language’s IClassifier implementation, we know it needs to classify text as Keyword, Identifier, Comment, and Number.  What we do is define a type called SimpleClassificationTypes like this:

   1: /// <summary>
   2: /// Represents a provider of <see cref="IClassificationType"/> objects for 
   3: /// the <c>Simple</c> language.
   4: /// </summary>
   5: public class SimpleClassificationTypes {
   6:  
   7:     private IHighlightingStyleRegistry registry;
   8:  
   9:     private IClassificationType comment;
  10:     private IClassificationType identifier;
  11:     private IClassificationType keyword;
  12:     private IClassificationType number;
  13:  
  14:     /// <summary>
  15:     /// Initializes a new instance of the <c>SimpleClassificationTypes</c> class.
  16:     /// </summary>
  17:     public SimpleClassificationTypes() : this(null) {}
  18:  
  19:     /// <summary>
  20:     /// Initializes a new instance of the <c>SimpleClassificationTypes</c> class.
  21:     /// </summary>
  22:     /// <param name="registry">The <see cref="IHighlightingStyleRegistry"/> 
  23:     /// to use when registering classification types and highlighting styles.</param>
  24:     public SimpleClassificationTypes(IHighlightingStyleRegistry registry) {
  25:         this.registry = registry ?? AmbientHighlightingStyleRegistry.Instance;
  26:     }
  27:  
  28:     /// <summary>
  29:     /// Gets the <see cref="IClassificationType"/> to use for comments.
  30:     /// </summary>
  31:     /// <value>The <see cref="IClassificationType"/> to use for comments.</value>
  32:     public IClassificationType Comment {
  33:         get {
  34:             if (comment == null) {
  35:                 comment = registry.GetClassificationType(ClassificationTypes.Comment.Key);
  36:                 if (comment == null) {
  37:                     comment = ClassificationTypes.Comment;
  38:                     registry.Register(comment, new HighlightingStyle(
  39:                         ClassificationTypes.Comment.Key, 
  40:                         Colors.Green, Colors.Transparent));
  41:                 }
  42:             }
  43:             return comment;
  44:         }
  45:     }
  46:  
  47:     // NOTE: Identifier, Keyword, Number props defined here similar to Comment
  48:  
  49:     /// <summary>
  50:     /// Registers all classification types and highlighting styles with 
  51:     /// the <see cref="IHighlightingStyleRegistry"/> used by this class.
  52:     /// </summary>
  53:     /// <returns>The collection of <see cref="IClassificationType"/> objects
  54:     /// that were registered.</returns>
  55:     public IEnumerable<IClassificationType> RegisterAll() {
  56:         return new IClassificationType[] {
  57:             this.Comment,
  58:             this.Identifier,
  59:             this.Keyword,
  60:             this.Number
  61:         };
  62:     }
  63:     
  64: }
  65:     

Effectively what we have now is a class that has properties which return the IClassificationType instances that should be used by the Simple language’s IClassifier.  The neat thing is that assuming you don’t do any pre-registration of classification types, it will register everything on-the-fly as needed.

If you wish to have a highlighting styles options page in your app, you can also call this at your app startup to pre-register everything, thereby ensuring that the dialog shows all classification types for the languages you support in your app.

   1: new SimpleClassificationTypes().RegisterAll();

Another change from yesterday is that we now only have a single registry instead of two.  The single IHighlightingStyleRegistry can provide the IHighlightingStyle for a specific IClassificationType, can enumerate the registered IClassificationType objects, can return the IClassificationType registered for a give classification type key, and can enumerate IHighlightingStyles that are registered.

Altogether it seems like a solid solution since you can be lazy and let it handle registering things as needed, or you can set everything up yourself at app startup.

We welcome your comments on this implementation.

IClassificationType inheritance

As Jesper posted in the comments to yesterday’s post, it would be cool to support logical inheritance of IClassificationType objects.  This way you could designate a tree of IClassificationType objects, like XML Comment Tag inherits XML Comment which inherits Comment and that inherits Text.  You could assign a IHighlightingStyle to any of those levels and during style resolution, it would take the lowest non-default property values for things like foreground color, etc. 

This feature is not implemented at this time, however it’s something we’ve thought about and have placeholders in our code where it can be added later.  What are your thoughts on this, and if we do it, should we allow single inheritance or multiple inheritance?

Tags: wpf, syntaxeditor
Filed under: Actipro, In development, WPF
Submit to DotNetKicks...
Permalink | Comments (2)

Related posts

SyntaxEditor for WPF - Need input on highlighting style configurationSorry we haven’t made any new SyntaxEditor for WPF posts recently.  We’ve been hamm...SyntaxEditor for WPF - Advanced themes and highlighting style featuresThe past several days we’ve been cleaning up code (running code analysis, fixing XML comment e...Integrating MGrammar DSL parsers with SyntaxEditor to implement syntax highlightingNow that the public beta of SyntaxEditor for WPF has been released, I’d like to show off a really ne...

Comments

March 24, 2009 at 17:32  

Jesper

I started writing this comment to push multiple inheritance as important, but then I realized that it's not just the classification type's inheritance that plays a role in styling; the context in the code does, too.

What if the XML tag is in a documentation comment? If it's also #if-ed out? If it's, on top of that, and this probably wouldn't be a documentation comment, is in a breakpoint highlight? What if it's in all these things and you've chosen to use other layer of custom classification on top. The list goes on and I'm starting to get brainfreeze just thinking about it. You could actually use something like CSS selectors to style this, with the classification being the class and the context being the elements. (That's clearly an exercise for the reader though.)

There's inherited behavior "from within", and overridden behavior "on top", in essence. I actually think the stacking factor of these is more what the example I used in my last comment (TextMate) does. (What's interesting is that as far as I know, that's its entire token concept; SyntaxEditor really solves this problem in an exhaustive way, but that's a nifty alternative approach for "just" getting the syntax highlighting.)

Jesper

March 24, 2009 at 22:40  

True, yet here in this case, we're only concerned with how the lexical parser for a language is classifying the text.

If something is #if'ed-out, it would then probably need to use some sort of pre-processor directive classification.  Alternatively, if you cared about highlighting the code in the section but maybe a bit faded out, you'd probably need a separate classification type for each thing like Keyword, etc. that was something like PreProcessorKeyword.

So do you vote single or multiple inheritance?

Bill Henning (Actipro)

Comments are closed
Copyright © 1999-2012 Actipro Software LLC. All rights reserved.
Home Actipro Software | Products | Download | Contact Us