AqiStar.TextBox Syntax Highlighting WPF control

High performance syntax coloring textbox for Windows Vista applications.

Initialization

To start using AqiStar.TextBox create a new WPF application in VS.NET 2005 - 2008 and add a reference to assembly AqiStar.TextBox.dll. Then paste following code into the XAML Visual Studio editor, build and run the project.

1 <Window x:Class="TextBoxDemo.Window2" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 xmlns:stb="clr-namespace:AqiStar;assembly=AqiStar.TextBox" 5 Title="Window1" Height="500" Width="500"> 6 <Grid Margin="40"> 7 <stb:TextBox x:Name="textBox" 8 FontSize="14" 9 FontFamily="Courier New" 10 LanguageMode="CSharp"> 11 </Grid> 12 </Window>

AqiStar.TextBox control language definition is selected with the property LanguageMode. Try highlighting and folding functionalities typing or copy from clipboard a sample CSharp code.

Go to top


Common properties

AqiStar.TextBox has similar properties to standard WPF TextBox. For example you can set TextTrimming to force line breaks to text exceeding horizontal available space. Other interesting properties are Zoom to zoom text area, CutCopyLineOnEmptySelection to enable/disable clipboard operations on current whole line when nothing is selected, TabSpaces and ConvertTabToSpaces to convert Tab key to spaces.

1 <Window x:Class="TextBoxDemo.Window2" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 xmlns:stb="clr-namespace:AqiStar;assembly=AqiStar.TextBox" 5 Title="Window1" Height="500" Width="500"> 6 <Grid Margin="40"> 7 <stb:TextBox x:Name="textBox" 8 FontSize="14" 9 FontFamily="Courier New" 10 LanguageMode="CSharp" 11 CutCopyLineOnEmptySelection="True" 12 TabSpaces="6" 13 ConvertTabToSpaces="True"> 14 </Grid> 15 </Window>

Go to top


Simple customization

AqiStar.TextBox provided a plenty of graphics elements that can be customized with easy. To get the complete and updated list please refer to documentation. In the following example we modify selection color and caret geometry.

1 <Window x:Class="TextBoxDemo.Window2" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 xmlns:stb="clr-namespace:AqiStar;assembly=AqiStar.TextBox" 5 Title="Window1" Height="500" Width="500"> 6 <Window.Resources> 7 <SolidColorBrush x:Key="{ComponentResourceKey TypeInTargetAssembly={x:Type stb:TextBox}, 8 ResourceId={x:Static stb:TextBoxElement.SelectionBackground}}" Color="Green" Opacity="0.3"/> 9 <SolidColorBrush x:Key="{ComponentResourceKey TypeInTargetAssembly={x:Type stb:TextBox}, 10 ResourceId={x:Static stb:TextBoxElement.CaretStroke}}" Color="Red"/> 11 </Window.Resources> 12 <Grid Margin="40"> 13 <stb:TextBox x:Name="textBox" 14 FontSize="14" 15 FontFamily="Courier New" 16 LanguageMode="CSharp" 17 CutCopyLineOnEmptySelection="True" 18 TabSpaces="6" 19 ConvertTabToSpaces="True"> 20 </Grid> 21 </Window>

Go to top


Custom Language Definitions

A language definition is an XML document which describes how AqiStar.TextBox should colorize text. AqiStar.TextBox is able to change font properties, background and foreground color of a portion of text. Create a language definition is very easy and this tutorial shows how can be colorized a MSSQL2000 stored procedure source code.

First of all a small list of notions:

  • Span: A span is a sequence of characters which share a common set of font settings. For an example consider a comment in a CSharp code: usually a comment starts with a special character or set of characters and ends with an EOL or an other special sequence of characters.

    To define a span we have to set a begin characters set, optionally an end character set, and a collection of font properties. Follows a XML header that define a comment span for MSSQL2000 language that begins with '--' characters:

    				
    1 <Span Name ="LineComment" 2 Foreground ="Green" 3 BreakAtEOL ="true"> 4 <Begin>--</Begin> 5 </Span>

    BreakAtEOL attribute set to True means that span ends at first next EOL.

  • Keyword: A keyword is a span corresponding to a single sequence of characters. An example is the word 'SELECT' in MSSQL2000 language.
  • RuleSet: Sometimes things are more complicated. Consider for an example how VS editor colorize xml document comments starting with '///' just before a CSharp function:

    /// <summary>
    ///
    Collapse a folder which contains a specified offset
    ///
    </summary>
    ///
    <param name="offset">Offset which identify a folder to collapse</param>

    In this case we have more child spans in the comment span which starts with '///'. To get the same behavior of VS we should apply to the comment span a set of rules to parse and colorize comment text. A RuleSet is a collection of span, keywords and other minor objects which define how to divide and colorize a portion of text delimited by a parent span. Follows an xml header of a RuleSet used to highlight above CSharp code:

    1 <Span Name ="DocLineComment" 2 RuleSet ="DocCommentSet" 3 Foreground ="Green" 4 BreakAtEOL ="true" > 5 <Begin Foreground ="Gray">///</Begin> 6 </Span> 7 <RuleSet Name ="DocCommentSet" 8 IgnoreCase ="false"> 9 <Delimiters><>~!@%^*()-+=|\#/{}[]:;"' , .?</Delimiters> 10 <Span Name ="XmlTag" 11 RuleSet ="XmlDocSet" 12 Foreground ="Gray" 13 BreakAtEOL ="true"> 14 <Begin><</Begin> 15 <End>></End> 16 </Span> 17 </RuleSet> 18 <RuleSet Name ="XmlDocSet" IgnoreCase ="false"> 19 <Delimiters><>~!@%^*()-+=|\#/{}[]:;"' , .?</Delimiters> 20 <Span Name ="String" 21 FontWeight="Bold" 22 Foreground ="Silver" 23 BreakAtEOL ="true"> 24 <Begin>"</Begin> 25 <End>"</End> 26 </Span> 27 <Keywords Name ="Punctuation" FontWeight="Bold" 28 Foreground ="Gray"> 29 <Keyword Name ="/" /> 30 <Keyword Name ="|" /> 31 <Keyword Name ="=" /> 32 </Keywords> 33 <Keywords Name ="SpecialComment" FontWeight="Bold" 34 Foreground="Gray"> 35 <Keyword Name ="c" /> 36 <Keyword Name ="code" /> 37 <Keyword Name ="example" /> 38 <Keyword Name ="exception" /> 39 <Keyword Name ="list" /> 40 <Keyword Name ="para" /> 41 <Keyword Name ="param" /> 42 .... 43 </Keywords> 44 </RuleSet>

    As shown above RuleSet can be nested and can contain different set of keywords. This flexibility is very useful when language to highlight is more complicated. Consider how can be easy to highlight script code in a html document.

    Following example shows how to link a language definition XML document to AqiStar.TextBox:

  • 1 <Window x:Class="TextBoxDemo.Window2" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 xmlns:stb="clr-namespace:AqiStar;assembly=AqiStar.TextBox" 5 Title="Window1" 6 Height="500" Width="500"> 7 <Grid Margin="40"> 8 <Window.Resources> 9 <ResourceDictionary> 10 <ResourceDictionary.MergedDictionaries> 11 <ResourceDictionary 12 Source="/TextBoxDemo;component/LanguageDefinitions/MSSQL2000.xaml"/> 13 </ResourceDictionary.MergedDictionaries> 14 </ResourceDictionary> 15 </Window.Resources> 16 <stb:TextBox x:Name="textBox" 17 FontSize="14" 18 FontFamily="Courier New" 19 LanguageMode="Custom" 20 CutCopyLineOnEmptySelection="True" 21 TabSpaces="6" 22 ConvertTabToSpaces="True"> 23 </Grid> 24 </Window>

    MSSQL2000.xaml is an embedded resource dictionary containing a test language definition:

    1 <wpf:ResourceDictionary 2 xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns="http://schemas.AqiStar.com/TextBox/LanguageDefinition" 4 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 5 xmlns:stb="clr-namespace:AqiStar;assembly=AqiStar.TextBox"> 6 <wpf:XmlDataProvider 7 x:Key="{wpf:ComponentResourceKey TypeInTargetAssembly={x:Type 8 stb:TextBox}, ResourceId={x:Static stb:LanguageModes.Custom}}" 9 IsAsynchronous="False"> 10 <x:XData > 11 <RuleSets 12 xmlns="http://schemas.AqiStar.com/TextBox/LanguageDefinition"> 13 <RuleSet IgnoreCase="false"> 14 <Delimiters>&<>~!%^*()-+=|\#/{}[]:;"' , .?</Delimiters> 15 <Span 16 Name ="LineComment" 17 Foreground ="Green" 18 BreakAtEOL ="true"> 19 <Begin>--</Begin> 20 </Span> 21 <Span Name ="String" 22 Foreground ="Magenta" 23 BreakAtEOL ="false"> 24 <Begin>'</Begin> <End>'</End> 25 </Span> 26 <Keywords Foreground="Gray"> 27 <Keyword Name ="ALL" /> 28 <Keyword Name ="AND" /> 29 <Keyword Name ="ANY" /> 30 <Keyword Name ="BETWEEN" /> 31 ... 32 </Keywords> 33 <Keywords Foreground="Blue"> 34 <Keyword Name ="SELECT" /> 35 <Keyword Name ="FROM" /> 36 <Keyword Name ="WHERE" /> 37 <Keyword Name ="ORDER" /> 38 ... 39 </Keywords> 40 </RuleSet> 41 </RuleSets> 42 </x:XData> 43 </wpf:XmlDataProvider> 44 </wpf:ResourceDictionary>

    Go to top


    Custom Formatting

    Using 'Custom Formatting' it's possible to change the style of one or more portions of text. This means that, independetly from the current syntax highlighting, user code can change forecolor as well as backcolor of single words among document text.

    This feature can be very useful to highlight code according to rules that are unknown at design time. Typical examples are the type/methods names of a CSharp code rendered with a different color as well as parameter names of a SQL procedure.

    C# source code with custom color for type names

    SQL procedures and parameters with custom color

    Adding a custom style to a text range is very easy. Following C# snippet shows how to change the foreground color and the font style of a portion of text:

    1 2 TextRunFormat testFormat = new TextRunFormat(); 3 testFormat.ForegroundBrush = Brushes.DarkCyan; 4 testFormat.FontStyle = FontStyles.Italic; 5 testFormat.TextDecorations.Add(TextDecorations.Underline); 6 _textBox.Formatting.ApplyFormat( 7 _textBox.Selection.OffsetStart, 8 _textBox.Selection.TextLength, 9 testFormat);

    ApplyFormat method accepts a text range and an object of type TextRunFormat which specifies the custom style to apply.

    Go to top