How to get started with the XAML Syntax Editor

Damyan Petev / Friday, September 28, 2012

XAML Syntax Editor - How to get startedThe XamSyntaxEditor is one of the recent additions to the Infragistics toolset. It made an odd voyage from being announced as a CTP not  with a release, but with a service release a bit over two months ago. And now it is on route to a XAML project near you, which was announced Brian Lagunas in What’s New in NetAdvantage for WPF & Silverlight 12.2: Part 1 – XAML Line of Business Controls.

A little bit on the side note – check out all the cool LoB stuff coming soon and make sure you don’t miss the What’s New in NetAdvantage for WPF & Silverlight 12.2: Part 2 – XAML Data Visualization Controls!

Now that you’ve got your basics lets jump into more details and examples.

 

Quick setup

First things first – you will need the references to the required assemblies and either the latest service release of either NetAdvantage for Silverlight or WPF. If you are lazy like me just take advantage of the new search bar in Visual Studio 2012 (search field in every place imaginable, yes! yes! Thank you Microsoft!):

XAML Syntax Editor in the Visual Studio 2012 Toolbox

Now in case you don’t feel like using a toolbox – the list includes the base platform assembly, “*.Undo.v12.2”, “*.Documents.TextDocument.v12.2” and “*.Controls.Editors.XamSyntaxEditor.v12.2”.

At this point you can setup the Syntax editor in both XAML and in code. (Note: Since the editor won’t do much without a document I consider them a unity and therefore setting up the editor also includes adding in the document). In the absolute most basic case your editor would look like so in XAML:

  1. xmlns:ig="http://schemas.infragistics.com/xaml"
  1. <ig:XamSyntaxEditor x:Name="editor">
  2.     <ig:XamSyntaxEditor.Document>
  3.         <ig:TextDocument/>
  4.     </ig:XamSyntaxEditor.Document>
  5. </ig:XamSyntaxEditor>

And in C#:

  1. using Infragistics.Controls.Editors;
  1. XamSyntaxEditor editor = new XamSyntaxEditor();
  2. editor.Document = new Infragistics.Documents.TextDocument();

Important thing to keep in mind – the Text Document is responsible for the desired language interaction(highlighting and error validation) and it’s default setting is ‘Plain Text’. That as you can imagine does not support either of the previously mentioned two very important features, so to get them you might want to set a language using the language property:

  1. editor.Document.Language = new Infragistics.Documents.CSharpLanguage();

Out of the box the editor also supports VB.NET. Of course you can set the very same property identically in XAML and run the app and you’ll get:

XAML Syntax Editor with highlithing and error reporting for C#

*Random C# code pasted form the code behind not included.

The last line is where I deleted a semicolon and a closing parenthesis so now you the familiar squiggly underlines in red are there to indicate something is indeed wrong. And language key words are colorized in nice blue as expected.

What’s in the box?

Grammar

Back in the "What’s new” post – did you notice Syntax Parsing Engine? If you did then +1 for you! Yup, the lexer is actually an autonomous engine that is part of the core experience the Editor control provides. It is responsible for the parsing, creating of syntax tree and error reporting. As mentioned it does come with support for  plain text, C# and VB.NET, but most importantly EBNF(Extended Backus–Naur Form ) so you can add additional language descriptions, but on that some other time.

Clipboard support and Undo/redo manager

Also by default the Syntax editor comes with clipboard support for all common actions and also support for unlimited undo/redo operations. Does that sound familiar? Remember the not so long ago introduced Undo / Redo Framework for XAML applications? Yup – it is right here with all it’s features – the unlimited operations stack of Undo Units, flexibility, etc. You can set up properties of the manager from the property of the Text Document:

  1. <ig:XamSyntaxEditor x:Name="editor">
  2.     <ig:XamSyntaxEditor.Document>
  3.         <ig:TextDocument >
  4.             <ig:TextDocument.UndoManager>
  5.                 <ig:UndoManager UndoLimit="20"/>
  6.             </ig:TextDocument.UndoManager>
  7.             <ig:TextDocument.Language>
  8.                 <ig:CSharpLanguage></ig:CSharpLanguage>
  9.             </ig:TextDocument.Language>
  10.         </ig:TextDocument>
  11.     </ig:XamSyntaxEditor.Document>
  12. </ig:XamSyntaxEditor>

Text Documents , Snapshots and Scanners

You might actually see this as the TextDocument framework, where the document represents a single text file and supports languages and operations like Load and Save, Append, Delete, Find and Replace and Insert and quite a lot more! It that you have (among other ways) a snapshot and the TextDocumentSnaphot represents the entire state (i.e. version) of a document. Every time a change is made to the document a new snapshot is created. Each snapshot is thread-safe and immutable. The snapshot provides access to lines, length, search method and a one to create a scanner. TextDocumentSnapshotScanner class targets a specific instance of a TextDocumentSnaphot and is created via the snapshot’s CreateScanner method. It provides neat methods to navigate between lines, words and tokens.

 

As you can tell the XamSyntaxEditor is quite the composite control but is it also very flexible and extensible. It strives to provide Editing experience much like the one you have in Visual Studio and just like it implements APIs that are familiar to Visual Studio extension writers.

Splitting and visual cues

If you have noticed above in the screenshot this is the Editor in Metro/Modern/Win8 style (seriously, got all confused lately!). Even though it doesn’t really have that much UI, there are still scroll bars and.. two odd rectangles. What I can’t show you on a screenshot is the mouse cue you get when on top of it as it prompts for resizing. That is because those are handles to drag and actually split the view!

Split handles, Verical and Horizontal split in the XAML Syntax Editor

*Sorry for the slightly large gif and slightly buggy recording :)

Both views are scrollable and maintain their own selection. The editor also has property to allow some or none of the splitting options to the end-user.

Commanding

The XamSyntaxEditor comes with a substantial set of commands! I mean there’s a list and it’s kind of long. From default things like Cut/Copy and Paste to split or moving the view in various directions to Undo manager commands and even to upper or lower case and selection. It’s a rich choice and I’ll just show you a small example of a two ButtonTools (consider them to be normal buttons if you will) on a XamRibbon:

  1. <igWPF:ButtonTool Content="Undo" SmallImage="/WpfApplication1;component/Images/undoArrow.png" IsQatCommonTool="True" >
  2.     <ig:Commanding.Command>
  3.         <igPrim:SyntaxEditorCommandSource EventName="Click" CommandType="Undo" />
  4.     </ig:Commanding.Command>
  5. </igWPF:ButtonTool>
  6. <igWPF:ButtonTool Content="Redo" SmallImage="/WpfApplication1;component/Images/redoArrow.png" IsQatCommonTool="True">
  7.     <ig:Commanding.Command>
  8.         <igPrim:SyntaxEditorCommandSource EventName="Click" CommandType="Redo" />
  9.     </ig:Commanding.Command>
  10. </igWPF:ButtonTool>

The syntax commanding source above contains all the command types I mentioned and probably some more.

Loading and Saving

The Syntax Editor’s Document is the one with the methods to load and save and both methods provide overloads to use either a string with the file name or a stream (the save method actually offers a few variations that can instead save using information from a previous call to the load method. I’ll throw a two fast examples of how to save locally but load from a remote file:

  1. /// <summary>
  2. /// Clear the document text (if any) and load some remote C# code file
  3. /// </summary>
  4. private void LoadDocument()
  5. {
  6.     //if (this.editor.Document.CurrentSnapshot.GetLines().Count() > 0)
  7.     //{
  8.     //    this.editor.Document.InitializeText(string.Empty);
  9.     //}
  10.     WebRequest wr = WebRequest.Create("https://dl.dropbox.com/u/76144077/somecode.cs");
  11.     HttpWebResponse resp = (HttpWebResponse)wr.GetResponse();
  12.     try
  13.     {
  14.         this.editor.Document.Load(resp.GetResponseStream());
  15.     }
  16.     catch (WebException ex)
  17.     {
  18.         MessageBox.Show(ex.Message);
  19.     }
  20. }
  21.  
  22. /// <summary>
  23. /// Save file locally.
  24. /// </summary>
  25. private void Save(object sender, RoutedEventArgs e)
  26. {
  27.     Stream stream;
  28.     System.Windows.Forms.SaveFileDialog dlg = new System.Windows.Forms.SaveFileDialog();
  29.     if (dlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
  30.     {
  31.         if ((stream = dlg.OpenFile()) != null)
  32.         {
  33.             this.editor.Document.Save(stream);
  34.             stream.Close();
  35.         }
  36.     }
  37. }

More!

There’s really so much more you can do as I mentioned the control is designed to be extensible, so once you gain substantial knowledge of the control you can customize it quite a bit. For now I’ll tease you with my pretty app where I have the above file loaded, the save, the commands in a ribbon , along with a search fields and a status bar with info bound to the Caret position for example:

  1. <TextBlock Text="{Binding Caret.TextLocation.Line, ElementName=editor, Mode=OneWay}"

And it looks and functions wonderfully:

XAML Syntax Editor application with clipboard, undo/redo, search, find and replace and status bar.

Stay tuned

This has obviously barely scratched the surface but it’s enough to get you started, provide basic info for the XAML Syntax Editor and show you some of the interesting commands, load and save methods and other properties.

As always, you can follow us on Twitter @DamyanPetev and @Infragistics and stay in touch on Facebook, Google+ and LinkedIn! Stay tuned some pretty exciting stuff are happening for the next release!