WPF: Create Syntax Highlighter for Any Language in 5 Minutes
Live Chat Icon For mobile
Live Chat Icon
Popular Categories.NET  (174).NET Core  (29).NET MAUI  (207)Angular  (109)ASP.NET  (51)ASP.NET Core  (82)ASP.NET MVC  (89)Azure  (41)Black Friday Deal  (1)Blazor  (218)BoldSign  (14)DocIO  (24)Essential JS 2  (107)Essential Studio  (200)File Formats  (66)Flutter  (133)JavaScript  (221)Microsoft  (119)PDF  (81)Python  (1)React  (100)Streamlit  (1)Succinctly series  (131)Syncfusion  (917)TypeScript  (33)Uno Platform  (3)UWP  (4)Vue  (45)Webinar  (51)Windows Forms  (61)WinUI  (68)WPF  (159)Xamarin  (161)XlsIO  (36)Other CategoriesBarcode  (5)BI  (29)Bold BI  (8)Bold Reports  (2)Build conference  (8)Business intelligence  (55)Button  (4)C#  (149)Chart  (131)Cloud  (15)Company  (443)Dashboard  (8)Data Science  (3)Data Validation  (8)DataGrid  (63)Development  (630)Doc  (8)DockingManager  (1)eBook  (99)Enterprise  (22)Entity Framework  (5)Essential Tools  (14)Excel  (40)Extensions  (22)File Manager  (7)Gantt  (18)Gauge  (12)Git  (5)Grid  (31)HTML  (13)Installer  (2)Knockout  (2)Language  (1)LINQPad  (1)Linux  (2)M-Commerce  (1)Metro Studio  (11)Mobile  (507)Mobile MVC  (9)OLAP server  (1)Open source  (1)Orubase  (12)Partners  (21)PDF viewer  (43)Performance  (12)PHP  (2)PivotGrid  (4)Predictive Analytics  (6)Report Server  (3)Reporting  (10)Reporting / Back Office  (11)Rich Text Editor  (12)Road Map  (12)Scheduler  (52)Security  (3)SfDataGrid  (9)Silverlight  (21)Sneak Peek  (31)Solution Services  (4)Spreadsheet  (11)SQL  (11)Stock Chart  (1)Surface  (4)Tablets  (5)Theme  (12)Tips and Tricks  (112)UI  (387)Uncategorized  (68)Unix  (2)User interface  (68)Visual State Manager  (2)Visual Studio  (31)Visual Studio Code  (19)Web  (594)What's new  (332)Windows 8  (19)Windows App  (2)Windows Phone  (15)Windows Phone 7  (9)WinRT  (26)
WPF : Create Syntax Editor for Any Language in 5 Minutes

WPF: Create Syntax Highlighter for Any Language in 5 Minutes

The Syncfusion WPF Syntax Highlighter is an easy-to-use and extensible control that allows users to create interactive code editor applications with advanced features such as built-in language highlighting, code editing, IntelliSense, undo and redo, search, and more.

The WPF Syntax highlighter tool provides built-in support for 10+ procedural and markup languages, including C#, Visual Basic, XAML, and JavaScript. It also comes with custom language configurations to apply syntax highlighting and outlining based on the user’s needs.

The WPF Syntax highlighter tool allows users to create a custom language with ease by inheriting one of the following base classes that contain a basic level of implementations and require a minimal set of configurations:

For detailed information on the implementation of these base classes, refer to custom language support documentation.

The ProceduralLanguageBase class contains syntax highlighting, outlining, and auto-mode IntelliSense implementations for procedural languages such as C# and Visual Basic, whereas the MarkupLanguageBase class contains syntax highlighting and outlining implementations for markup languages such as XAML and XML, and scripting languages such as JavaScript.

Let’s see how to configure a custom language in the Syntax Highlighter.

Configuring a custom language: IronPython

The following steps explain how to a create syntax highlighter in WPF for the custom language IronPython:

Step 1: Create a new class, inheriting from the ProceduralLanguageBase class.

Create a new class inheriting from the ProceduralLanguageBase class since IronPython’s start and end tags match with procedural languages. Set the basic properties of the language in the inherited class by using the following code:

public class PythonLanguage : ProceduralLanguageBase
{
    public PythonLanguage(EditControl control) : base(control)
    {
        this.Name = "Python";
        this.FileExtension = "py";
        this.ApplyColoring = true;
        this.SupportsIntellisense = false;
        this.SupportsOutlining = true;
        this.TextForeground = Brushes.Black;
    }
}

Step 2: Create a format collection for IronPython.

Create a collection of IFormat-implemented classes to apply in the Formats property of the custom language to decide the color applied to tokens by using the following code.

<syncfusion:FormatsCollection x:Key="pythonLanguageFormats">
<syncfusion:EditFormats Foreground="Green" FormatName="CommentFormat"/>
<syncfusion:EditFormats Foreground="Black" FormatName="MultilineCommentFormat"/>
<syncfusion:EditFormats Foreground="Blue" FormatName="KeywordFormat"/>
<syncfusion:EditFormats Foreground="Navy" FormatName="OperatorFormat"/>
<syncfusion:EditFormats Foreground="Gray" FormatName="LiteralsFormat"/>
</syncfusion:FormatsCollection>

Step 3: Create a Lexem collection for IronPython.

Create a collection of ILexem-implemented classes—which decides keywords, comments, literals, and preprocessor information for the custom language—by using the following code.

<syncfusion:LexemCollection x:Key="pythonLanguageLexems">
<syncfusion:Lexem StartText="class \w+[\s:\w,()]+" IsRegex="True" IsMultiline="True" ContainsEndText="True" LexemType="CodeSnippet" EndText="\r\n" ScopeLevel="Class" ShowAlternateIntellisenseText="True" IntellisenseDisplayText="class"/>
<syncfusion:Lexem StartText="def \w+[\s:\w,()]+" IsRegex="True" IsMultiline="True" ContainsEndText="True" LexemType="CodeSnippet" EndText="\r\n" ScopeLevel="Member" ShowAlternateIntellisenseText="True" IntellisenseDisplayText="def"/>
<syncfusion:Lexem StartText="#" EndText="\r\n" IsMultiline="False" ContainsEndText="True" LexemType="Comment" FormatName="CommentFormat"/>
<syncfusion:Lexem StartText=""""" EndText=""""" IsMultiline="True" ContainsEndText="True" LexemType="Comment" FormatName="CommentFormat" />
<syncfusion:Lexem StartText="and" ContainsEndText="False" IsMultiline="False" LexemType="Keyword" FormatName="KeywordFormat"/>
<syncfusion:Lexem StartText="as" ContainsEndText="False" IsMultiline="False" LexemType="Keyword" FormatName="KeywordFormat"/>
<syncfusion:Lexem StartText="assert" ContainsEndText="False" IsMultiline="False" LexemType="Keyword" FormatName="KeywordFormat"/>
<syncfusion:Lexem StartText="break" ContainsEndText="False" IsMultiline="False" LexemType="Keyword" FormatName="KeywordFormat"/>
<syncfusion:Lexem StartText="class" ContainsEndText="False" IsMultiline="False" LexemType="Keyword" FormatName="KeywordFormat"/>
<syncfusion:Lexem StartText="continue" ContainsEndText="False" IsMultiline="False" LexemType="Keyword" FormatName="KeywordFormat"/>
<syncfusion:Lexem StartText="def" ContainsEndText="False" IsMultiline="False" LexemType="Keyword" FormatName="KeywordFormat"/>
<syncfusion:Lexem StartText="del" ContainsEndText="False" IsMultiline="False" LexemType="Keyword" FormatName="KeywordFormat"/>
<syncfusion:Lexem StartText="elif" ContainsEndText="False" IsMultiline="False" LexemType="Keyword" FormatName="KeywordFormat"/>
<syncfusion:Lexem StartText="else" ContainsEndText="False" IsMultiline="False" LexemType="Keyword" FormatName="KeywordFormat"/>
<syncfusion:Lexem StartText="except" ContainsEndText="False" IsMultiline="False" LexemType="Keyword" FormatName="KeywordFormat"/>
<syncfusion:Lexem StartText="exec" ContainsEndText="False" IsMultiline="False" LexemType="Keyword" FormatName="KeywordFormat"/>
<syncfusion:Lexem StartText="finally" ContainsEndText="False" IsMultiline="False" LexemType="Keyword" FormatName="KeywordFormat"/>
<syncfusion:Lexem StartText="for" ContainsEndText="False" IsMultiline="False" LexemType="Keyword" FormatName="KeywordFormat"/>
<syncfusion:Lexem StartText="from" ContainsEndText="False" IsMultiline="False" LexemType="Keyword" FormatName="KeywordFormat"/>
<syncfusion:Lexem StartText="global" ContainsEndText="False" IsMultiline="False" LexemType="Keyword" FormatName="KeywordFormat"/>
<syncfusion:Lexem StartText="if" ContainsEndText="False" IsMultiline="False" LexemType="Keyword" FormatName="KeywordFormat"/>
<syncfusion:Lexem StartText="import" ContainsEndText="False" IsMultiline="False" LexemType="Keyword" FormatName="KeywordFormat"/>
<syncfusion:Lexem StartText="in" ContainsEndText="False" IsMultiline="False" LexemType="Keyword" FormatName="KeywordFormat"/>
<syncfusion:Lexem StartText="is" ContainsEndText="False" IsMultiline="False" LexemType="Keyword" FormatName="KeywordFormat"/>
<syncfusion:Lexem StartText="lambda" ContainsEndText="False" IsMultiline="False" LexemType="Keyword" FormatName="KeywordFormat"/>
<syncfusion:Lexem StartText="not" ContainsEndText="False" IsMultiline="False" LexemType="Keyword" FormatName="KeywordFormat"/>
<syncfusion:Lexem StartText="or" ContainsEndText="False" IsMultiline="False" LexemType="Keyword" FormatName="KeywordFormat"/>
<syncfusion:Lexem StartText="pass" ContainsEndText="False" IsMultiline="False" LexemType="Keyword" FormatName="KeywordFormat"/>
<syncfusion:Lexem StartText="print" ContainsEndText="False" IsMultiline="False" LexemType="Keyword" FormatName="KeywordFormat"/>
<syncfusion:Lexem StartText="raise" ContainsEndText="False" IsMultiline="False" LexemType="Keyword" FormatName="KeywordFormat"/>
<syncfusion:Lexem StartText="return" ContainsEndText="False" IsMultiline="False" LexemType="Keyword" FormatName="KeywordFormat"/>
<syncfusion:Lexem StartText="try" ContainsEndText="False" IsMultiline="False" LexemType="Keyword" FormatName="KeywordFormat"/>
<syncfusion:Lexem StartText="while" ContainsEndText="False" IsMultiline="False" LexemType="Keyword" FormatName="KeywordFormat"/>
<syncfusion:Lexem StartText="with" ContainsEndText="False" IsMultiline="False" LexemType="Keyword" FormatName="KeywordFormat"/>
<syncfusion:Lexem StartText="yeild" ContainsEndText="False" IsMultiline="False" LexemType="Keyword" FormatName="KeywordFormat"/>
<syncfusion:Lexem StartText=""" EndText=""" IsMultiline="False" LexemType="Literals" FormatName="LiteralsFormat"/>
<syncfusion:Lexem StartText="(" ContainsEndText="False" IsMultiline="False" LexemType="Operator" FormatName="OperatorFormat"/>
<syncfusion:Lexem StartText=")" ContainsEndText="False" IsMultiline="False" LexemType="Operator" FormatName="OperatorFormat"/>
<syncfusion:Lexem StartText="[" ContainsEndText="False" IsMultiline="False" LexemType="Operator" FormatName="OperatorFormat"/>
<syncfusion:Lexem StartText="]" ContainsEndText="False" IsMultiline="False" LexemType="Operator" FormatName="OperatorFormat"/>
<syncfusion:Lexem StartText="\{" ContainsEndText="False" IsMultiline="False" LexemType="Operator" FormatName="OperatorFormat"/>
<syncfusion:Lexem StartText="\}" ContainsEndText="False" IsMultiline="False" LexemType="Operator" FormatName="OperatorFormat"/>
<syncfusion:Lexem StartText="." ContainsEndText="False" IsMultiline="False" LexemType="Operator" FormatName="OperatorFormat"/>
<syncfusion:Lexem StartText="," ContainsEndText="False" IsMultiline="False" LexemType="Operator" FormatName="OperatorFormat"/>
<syncfusion:Lexem StartText=";" ContainsEndText="False" IsMultiline="False" LexemType="Operator" FormatName="OperatorFormat"/>
<syncfusion:Lexem StartText=":" ContainsEndText="False" IsMultiline="False" LexemType="Operator" FormatName="OperatorFormat"/>
<syncfusion:Lexem StartText="+" ContainsEndText="False" IsMultiline="False" LexemType="Operator" FormatName="OperatorFormat"/>
<syncfusion:Lexem StartText="-" ContainsEndText="False" IsMultiline="False" LexemType="Operator" FormatName="OperatorFormat"/>
<syncfusion:Lexem StartText="/" ContainsEndText="False" IsMultiline="False" LexemType="Operator" FormatName="OperatorFormat"/>
<syncfusion:Lexem StartText="%" ContainsEndText="False" IsMultiline="False" LexemType="Operator" FormatName="OperatorFormat"/>
<syncfusion:Lexem StartText="^" ContainsEndText="False" IsMultiline="False" LexemType="Operator" FormatName="OperatorFormat"/>
<syncfusion:Lexem StartText="*" ContainsEndText="False" IsMultiline="False" LexemType="Operator" FormatName="OperatorFormat"/>
<syncfusion:Lexem StartText="**" ContainsEndText="False" IsMultiline="False" LexemType="Operator" FormatName="OperatorFormat"/>
<syncfusion:Lexem StartText="|" ContainsEndText="False" IsMultiline="False" LexemType="Operator" FormatName="OperatorFormat"/>
<syncfusion:Lexem StartText="|=" ContainsEndText="False" IsMultiline="False" LexemType="Operator" FormatName="OperatorFormat"/>
<syncfusion:Lexem StartText="&" ContainsEndText="False" IsMultiline="False" LexemType="Operator" FormatName="OperatorFormat"/>
<syncfusion:Lexem StartText="~" ContainsEndText="False" IsMultiline="False" LexemType="Operator" FormatName="OperatorFormat"/>
<syncfusion:Lexem StartText="=" ContainsEndText="False" IsMultiline="False" LexemType="Operator" FormatName="OperatorFormat"/>
<syncfusion:Lexem StartText="<" ContainsEndText="False" IsMultiline="False" LexemType="Operator" FormatName="OperatorFormat"/>
<syncfusion:Lexem StartText=">" ContainsEndText="False" IsMultiline="False" LexemType="Operator" FormatName="OperatorFormat"/>
<syncfusion:Lexem StartText="==" ContainsEndText="False" IsMultiline="False" LexemType="Operator" FormatName="OperatorFormat"/>
<syncfusion:Lexem StartText="!=" ContainsEndText="False" IsMultiline="False" LexemType="Operator" FormatName="OperatorFormat"/>
<syncfusion:Lexem StartText="<=" ContainsEndText="False" IsMultiline="False" LexemType="Operator" FormatName="OperatorFormat"/>
<syncfusion:Lexem StartText=">=" ContainsEndText="False" IsMultiline="False" LexemType="Operator" FormatName="OperatorFormat"/>
<syncfusion:Lexem StartText="+=" ContainsEndText="False" IsMultiline="False" LexemType="Operator" FormatName="OperatorFormat"/>
<syncfusion:Lexem StartText="-=" ContainsEndText="False" IsMultiline="False" LexemType="Operator" FormatName="OperatorFormat"/>
<syncfusion:Lexem StartText="*=" ContainsEndText="False" IsMultiline="False" LexemType="Operator" FormatName="OperatorFormat"/>
<syncfusion:Lexem StartText="%=" ContainsEndText="False" IsMultiline="False" LexemType="Operator" FormatName="OperatorFormat"/>
<syncfusion:Lexem StartText="/=" ContainsEndText="False" IsMultiline="False" LexemType="Operator" FormatName="OperatorFormat"/>
<syncfusion:Lexem StartText="&=" ContainsEndText="False" IsMultiline="False" LexemType="Operator" FormatName="OperatorFormat"/>
<syncfusion:Lexem StartText="^=" ContainsEndText="False" IsMultiline="False" LexemType="Operator" FormatName="OperatorFormat"/>
<syncfusion:Lexem StartText="|=" ContainsEndText="False" IsMultiline="False" LexemType="Operator" FormatName="OperatorFormat"/>
<syncfusion:Lexem StartText="<<" ContainsEndText="False" IsMultiline="False" LexemType="Operator" FormatName="OperatorFormat"/>
<syncfusion:Lexem StartText="<<=" ContainsEndText="False" IsMultiline="False" LexemType="Operator" FormatName="OperatorFormat"/>
<syncfusion:Lexem StartText="=>" ContainsEndText="False" IsMultiline="False" LexemType="Operator" FormatName="OperatorFormat"/>
<syncfusion:Lexem StartText="<>" ContainsEndText="False" IsMultiline="False" LexemType="Operator" FormatName="OperatorFormat"/>
<syncfusion:Lexem StartText=">>=" ContainsEndText="False" IsMultiline="False" LexemType="Operator" FormatName="OperatorFormat"/>
<syncfusion:Lexem StartText="**;=" ContainsEndText="False" IsMultiline="False" LexemType="Operator" FormatName="OperatorFormat"/>
</syncfusion:LexemCollection>

Step 4: Assign Lexem and Format properties to custom python language.

Initialize and assign Lexem and Format collections to the custom Python language.

PythonLanguage customLanguage = new PythonLanguage(obj as EditControl);
customLanguage.Lexem = this.Resources["pythonLanguageLexems"] as LexemCollection;
customLanguage.Formats = this.Resources["pythonLanguageFormats"] as FormatsCollection;

If there is still any need to customize colors for syntax, the ApplyColoring method can be overridden to achieve further customization of colors. Similarly, to customize outlining, the ApplyExpandCollapse method can be overridden. Please refer to this documentation topic for detailed information on the usage of overridden methods.

After executing the above configurations, we will get the following output for the IronPython language:

WPF Syntax Editor Customized to Support IronPyton
WPF Syntax Highlighter Customized to Support IronPyton

References

To learn more, refer to the documentation custom language support and configuring custom language using WPF syntax highlighter demo.

Conclusion

I hope you now feel confident enough to create a custom language Syntax Highlighter in WPF on your own in just four simple steps. This feature will definitely help you extend the usage of the Syntax Highlighter beyond the supported procedural and markup languages.

If you want to play around with the Syntax Highlighter, you’ll be happy to know that our WPF demos are now available in the Microsoft Store, and our .NET Core demos are available in the App Center.

For existing customers, the newest version of Essential Studio is available for download from the License and Downloads page. If you are not yet a Syncfusion customer, you can try our 30-day free trial to check out our available features.

If you wish to send us feedback or ask any questions, please use the comments section below. You can also contact us through our support forumsDirect-Trac, or feedback portal. We are always happy to assist you!

Tags:

Share this post:

Comments (2)

This is great, thank you! I was wondering what my options are with Blazor? What would you recommend for the web? Also, I understand that you support .NET 5 now, is that right?

Hi Alex,

Thanks for your interest in Syncfusion Web products.

Currently, the syntax editor component is not available in our Syncfusion Blazor components suite. Already, we have logged a feature request for this new component.
https://www.syncfusion.com/feedback/22421/syntax-editor-component-in-blazor

Yes, we have support for NET 5.
https://blazor.syncfusion.com/documentation/system-requirements/

Kindly get back to us if you need any other details.

Regards,
Rajendran R.

Comments are closed.

Popular Now

Be the first to get updates

Subscribe RSS feed

Be the first to get updates

Subscribe RSS feed