首页  编辑  

C#语法高亮简单方法(使用DevExpress RichEditControl)

Tags: /C#/界面处理/   Date Created:
C#中,语法高亮(JSON)的简单方法:
1. 放置DevExpress RichEditControl控件recEditor。
2. 在窗体构造函数当中,添加代码:
recEditor.ReplaceService<ISyntaxHighlightService>(new MySyntaxHighlightService(recEditor));
3. 在加载文本内容的地方,写上类似代码:
recEditor.LoadDocument(form.EditFile);
4. 下面是语法高亮核心代码:
/// <summary>
///  This class implements the Execute method of the ISyntaxHighlightService interface to parse and colorize the text.
/// </summary>
public class MySyntaxHighlightService : ISyntaxHighlightService
{
    readonly RichEditControl syntaxEditor;
    SyntaxColors syntaxColors;
    SyntaxHighlightProperties commentProperties;
    SyntaxHighlightProperties keywordProperties;
    SyntaxHighlightProperties stringProperties;
    SyntaxHighlightProperties xmlCommentProperties;
    SyntaxHighlightProperties textProperties;

    public MySyntaxHighlightService(RichEditControl syntaxEditor)
    {
        this.syntaxEditor = syntaxEditor;
        syntaxColors = new SyntaxColors(UserLookAndFeel.Default);
    }

    void HighlightSyntax(TokenCollection tokens)
    {
        commentProperties = new SyntaxHighlightProperties();
        commentProperties.ForeColor = syntaxColors.CommentColor;

        keywordProperties = new SyntaxHighlightProperties();
        keywordProperties.ForeColor = syntaxColors.KeywordColor;

        stringProperties = new SyntaxHighlightProperties();
        stringProperties.ForeColor = syntaxColors.StringColor;

        xmlCommentProperties = new SyntaxHighlightProperties();
        xmlCommentProperties.ForeColor = syntaxColors.XmlCommentColor;

        textProperties = new SyntaxHighlightProperties();
        textProperties.ForeColor = syntaxColors.TextColor;

        if (tokens == null || tokens.Count == 0)
            return;

        Document document = syntaxEditor.Document;
        //CharacterProperties cp = document.BeginUpdateCharacters(0, 1);
        List<SyntaxHighlightToken> syntaxTokens = new List<SyntaxHighlightToken>(tokens.Count);
        foreach (Token token in tokens)
        {
            HighlightCategorizedToken((CategorizedToken)token, syntaxTokens);
        }
        document.ApplySyntaxHighlight(syntaxTokens);
        //document.EndUpdateCharacters(cp);
    }

    void HighlightCategorizedToken(CategorizedToken token, List<SyntaxHighlightToken> syntaxTokens)
    {
        Color backColor = syntaxEditor.ActiveView.BackColor;
        TokenCategory category = token.Category;
        if (category == TokenCategory.Comment)
            syntaxTokens.Add(SetTokenColor(token, commentProperties, backColor));
        else if (category == TokenCategory.Keyword)
            syntaxTokens.Add(SetTokenColor(token, keywordProperties, backColor));
        else if (category == TokenCategory.String)
            syntaxTokens.Add(SetTokenColor(token, stringProperties, backColor));
        else if (category == TokenCategory.XmlComment)
            syntaxTokens.Add(SetTokenColor(token, xmlCommentProperties, backColor));
        else
            syntaxTokens.Add(SetTokenColor(token, textProperties, backColor));
    }

    SyntaxHighlightToken SetTokenColor(Token token, SyntaxHighlightProperties foreColor, Color backColor)
    {
        if (syntaxEditor.Document.Paragraphs.Count < token.Range.Start.Line)
            return null;
        int paragraphStart = DocumentHelper.GetParagraphStart(syntaxEditor.Document.Paragraphs[token.Range.Start.Line - 1]);
        int tokenStart = paragraphStart + token.Range.Start.Offset - 1;
        if (token.Range.End.Line != token.Range.Start.Line)
            paragraphStart = DocumentHelper.GetParagraphStart(syntaxEditor.Document.Paragraphs[token.Range.End.Line - 1]);

        int tokenEnd = paragraphStart + token.Range.End.Offset - 1;
        return new SyntaxHighlightToken(tokenStart, tokenEnd - tokenStart, foreColor);
    }

    #region #ISyntaxHighlightServiceMembers
    public void Execute()
    {
        string newText = syntaxEditor.Text;
        // Determine language by file extension.
        // string ext = System.IO.Path.GetExtension(syntaxEditor.Options.DocumentSaveOptions.CurrentFileName);
        // ParserLanguageID lang_ID = ParserLanguage.FromFileExtension(ext);

        ParserLanguageID lang_ID = ParserLanguageID.JavaScript;
        if (lang_ID == ParserLanguageID.None) return;
        ITokenCategoryHelper tokenHelper = TokenCategoryHelperFactory.CreateHelper(lang_ID);
        TokenCollection highlightTokens;
        highlightTokens = tokenHelper.GetTokens(newText);
        HighlightSyntax(highlightTokens);
    }

    public void ForceExecute()
    {
        Execute();
    }
    #endregion #ISyntaxHighlightServiceMembers
}

/// <summary>
///  This class provides colors to highlight the tokens.
/// </summary>
public class SyntaxColors
{
    static Color DefaultCommentColor
    {
        get { return Color.Green; }
    }
    static Color DefaultKeywordColor
    {
        get { return Color.Blue; }
    }
    static Color DefaultStringColor
    {
        get { return Color.Brown; }
    }
    static Color DefaultXmlCommentColor
    {
        get { return Color.Gray; }
    }
    static Color DefaultTextColor
    {
        get { return Color.Black; }
    }
    UserLookAndFeel lookAndFeel;

    public Color CommentColor
    {
        get { return GetCommonColorByName(CommonSkins.SkinInformationColor, DefaultCommentColor); }
    }
    public Color KeywordColor
    {
        get { return GetCommonColorByName(CommonSkins.SkinQuestionColor, DefaultKeywordColor); }
    }
    public Color TextColor
    {
        get { return GetCommonColorByName(CommonColors.WindowText, DefaultTextColor); }
    }
    public Color XmlCommentColor
    {
        get { return GetCommonColorByName(CommonColors.DisabledText, DefaultXmlCommentColor); }
    }

    public Color StringColor
    {
        get { return GetCommonColorByName(CommonSkins.SkinWarningColor, DefaultStringColor); }
    }

    public SyntaxColors(UserLookAndFeel lookAndFeel)
    {
        this.lookAndFeel = lookAndFeel;
    }

    Color GetCommonColorByName(string colorName, Color defaultColor)
    {
        Skin skin = CommonSkins.GetSkin(lookAndFeel);
        if (skin == null)
            return defaultColor;
        return skin.Colors[colorName];
    }
}