Layers

RadSyntaxEditor renders its elements on different layers based on the types of tags that are used. It does so with the help of a UILayersBuilder class. The default builder renders the following stack of layers:

  • TextHighlightUILayer
  • TextBorderUILayer
  • TextUnderlineUILayer
  • TextUILayer
  • TextToolTipUILayer
  • SelectionUILayer
  • FoldingUILayer

These layers are responsible for drawing different elements on the canvas of the RadSyntaxEditor control. For example, the FoldingUILayer generates a FoldedRegionButton with a tool-tip, containing the folded text.

Custom Layer and UILayersBuilder

We will now create a custom layer which will be responsible for highlighting any comments in the code. For the purpose, we need to override the GetLinePartUIElement method and return a FrameworkElement to be drawn on the layer - a LightGray rectangle in this case.

Creating a custom layer

public class CommentsUILayer : LineBasedUILayer<Telerik.WinForms.SyntaxEditor.Core.Tagging.ClassificationTag>
{
    public override string Name
    {
        get
        {
            return "UnderlineOnMouseOver";
        }
    }

    public CommentsUILayer()
    {
    }

    protected override FrameworkElement GetLinePartUIElement(Telerik.WinForms.SyntaxEditor.Core.Tagging.ClassificationTag tag,
        Telerik.WinForms.SyntaxEditor.Core.Text.Span span, UIUpdateContext updateContext)
    {
        if (tag.ClassificationType != Telerik.WinForms.SyntaxEditor.Core.Tagging.ClassificationTypes.Comment)
        {
            return null;
        }

        Rect rect = updateContext.Editor.GetLinePartBoundingRectangle(span);
        Telerik.WinControls.SyntaxEditor.UI.Rectangle rectangle = this.GetElementFromPool<Telerik.WinControls.SyntaxEditor.UI.Rectangle>();
        rectangle.ShouldHandleMouseInput = true;
        rectangle.Width = rect.Width;
        rectangle.Height = rect.Height;
        rectangle.Fill = new SolidBrush(System.Drawing.Color.FromArgb(100, System.Drawing.Color.LightGray));

        return rectangle;
    }

    protected override void ResetPooledElementProperties(object element)
    {
        Telerik.WinControls.SyntaxEditor.UI.Rectangle rectangle = (Telerik.WinControls.SyntaxEditor.UI.Rectangle)element;
        rectangle.ClearValue(Telerik.WinControls.SyntaxEditor.UI.Rectangle.FillProperty);
    }
}

Public Class CommentsUILayer
    Inherits LineBasedUILayer(Of Telerik.WinForms.SyntaxEditor.Core.Tagging.ClassificationTag)
    Public Overrides ReadOnly Property Name As String
        Get
            Return "UnderlineOnMouseOver"
        End Get
    End Property
    Public Sub New()
    End Sub
    Protected Overrides Function GetLinePartUIElement(ByVal tag As Telerik.WinForms.SyntaxEditor.Core.Tagging.ClassificationTag, _
    ByVal span As Telerik.WinForms.SyntaxEditor.Core.Text.Span, ByVal updateContext As UIUpdateContext) _
    As Telerik.WinControls.SyntaxEditor.UI.FrameworkElement
        If Not tag.ClassificationType.Equals(Telerik.WinForms.SyntaxEditor.Core.Tagging.ClassificationTypes.Comment) Then
            Return Nothing
        End If
        Dim rect As Telerik.WinControls.SyntaxEditor.UI.Rect = updateContext.Editor.GetLinePartBoundingRectangle(span)
        Dim rectangle As Telerik.WinControls.SyntaxEditor.UI.Rectangle = Me.GetElementFromPool(Of Telerik.WinControls.SyntaxEditor.UI.Rectangle)()
        rectangle.ShouldHandleMouseInput = True
        rectangle.Width = rect.Width
        rectangle.Height = rect.Height
        rectangle.Fill = New SolidBrush(System.Drawing.Color.FromArgb(100, System.Drawing.Color.LightGray))
        Return rectangle
    End Function
    Protected Overrides Sub ResetPooledElementProperties(ByVal element As Object)
        Dim rectangle As Telerik.WinControls.SyntaxEditor.UI.Rectangle = CType(element, Telerik.WinControls.SyntaxEditor.UI.Rectangle)
        rectangle.ClearValue(Telerik.WinControls.SyntaxEditor.UI.Rectangle.FillProperty)
    End Sub
End Class

For our custom layer to be recognized by the RadSyntaxEditor we need to add it to the UILayerStack. We can do so by creating a custom UILayersBuilder and overriding its BuildUILayers method.

Using the custom layer in a custom layers builder


public class CustomUILayersBuilder : Telerik.WinForms.Controls.SyntaxEditor.UI.Layers.UILayersBuilder
{
    private CommentsUILayer customLayer;

    public override void BuildUILayers(UILayerStack uiLayers)
    {
        base.BuildUILayers(uiLayers);

        customLayer = new CommentsUILayer();
        uiLayers.AddLast(customLayer);
    }

    public void ClearCustomLayer()
    {
        foreach (Telerik.WinControls.SyntaxEditor.UI.Rectangle item in this.customLayer.Container.Children.OfType<Telerik.WinControls.SyntaxEditor.UI.Rectangle>())
        {
            item.Fill = System.Drawing.Brushes.Transparent;
        }
    }
}

Public Class CustomUILayersBuilder
    Inherits Telerik.WinForms.Controls.SyntaxEditor.UI.Layers.UILayersBuilder
    Private customLayer As CommentsUILayer
    Public Overrides Sub BuildUILayers(ByVal uiLayers As Telerik.WinForms.Controls.SyntaxEditor.UI.Layers.UILayerStack)
        MyBase.BuildUILayers(uiLayers)
        customLayer = New CommentsUILayer()
        uiLayers.AddLast(customLayer)
    End Sub
    Public Sub ClearCustomLayer()
        For Each item As Telerik.WinControls.SyntaxEditor.UI.Rectangle In Me.customLayer.Container.Children.OfType(Of Telerik.WinControls.SyntaxEditor.UI.Rectangle)()
            item.Fill = System.Drawing.Brushes.Transparent
        Next
    End Sub
End Class

Finally, we need to set the UILayersBuilder to an instance of the custom layers builder class.

Using the custom layers builder

this.radSyntaxEditor1.SyntaxEditorElement.UILayersBuilder = new CustomUILayersBuilder();

Me.RadSyntaxEditor1.SyntaxEditorElement.UILayersBuilder = New CustomUILayersBuilder()

Consider that we have the following taggers applied to RadSyntaxEditor:


CSharpTagger currentLanguageTagger = new Telerik.WinForms.Controls.SyntaxEditor.Taggers.CSharpTagger(this.radSyntaxEditor1.SyntaxEditorElement);
this.radSyntaxEditor1.TaggersRegistry.RegisterTagger(currentLanguageTagger);

CSharpFoldingTagger foldingTagger = new Telerik.WinForms.Controls.SyntaxEditor.Taggers.CSharpFoldingTagger(this.radSyntaxEditor1.SyntaxEditorElement);
foldingTagger.FoldingRegionDefinitions.Add(new FoldingRegionDefinition("#if", "#endif"));
radSyntaxEditor1.TaggersRegistry.RegisterTagger(foldingTagger);

Dim currentLanguageTagger As CSharpTagger = New Telerik.WinForms.Controls.SyntaxEditor.Taggers.CSharpTagger(Me.RadSyntaxEditor1.SyntaxEditorElement)
Me.RadSyntaxEditor1.TaggersRegistry.RegisterTagger(currentLanguageTagger)
Dim foldingTagger As CSharpFoldingTagger = New Telerik.WinForms.Controls.SyntaxEditor.Taggers.CSharpFoldingTagger(Me.RadSyntaxEditor1.SyntaxEditorElement)
foldingTagger.FoldingRegionDefinitions.Add(New FoldingRegionDefinition("#if", "#endif"))
RadSyntaxEditor1.TaggersRegistry.RegisterTagger(foldingTagger)

Once you run the application, the comments are expected to be colored as it is illustrated below:

Figure 1: Default comments' style

syntax-editor-features-layers001

Figure 2: Custom layer for comments

syntax-editor-features-layers002

In this article
Not finding the help you need? Improve this article