RichEditControl作为强大的富文本编辑器,支持自定义高亮语法,这就可以实现编辑语言、SQL语言和其他标记文本的显示。很香,下面是自定义XML高亮显示的效果。
需要实现ISyntaxHighlightService接口的方法即可,自定义类如下:
using System.Collections.Generic; using System.Drawing; using DevExpress.XtraRichEdit.API.Native; using DevExpress.XtraRichEdit.Services; namespace Dev.Tool.Xml { /// <summary> /// 自定义语法高亮服务 /// </summary> public class CustomSyntaxHighlightService : ISyntaxHighlightService { #region 私有变量 //文档 private readonly Document _document; //默认语法高亮颜色 private readonly SyntaxHighlightProperties _defaultSettings = new SyntaxHighlightProperties() { ForeColor = Color.Brown }; //关键字语法高亮颜色 private readonly SyntaxHighlightProperties _keywordSettings = new SyntaxHighlightProperties() { ForeColor = Color.Blue }; //字符串语法高亮颜色 private readonly SyntaxHighlightProperties _stringSettings = new SyntaxHighlightProperties() { ForeColor = Color.Black }; readonly string[] _keywords = {"version", "encoding", "application", "name", "isnull", "iskey", "value", "property", "=", "</", "/>", "<", ">"}; #endregion #region 构造函数 public CustomSyntaxHighlightService(Document document) { this._document = document; } #endregion #region 接口成员 public void ForceExecute() { Execute(); } public void Execute() { _document.ApplySyntaxHighlight(ParseTokens()); } #endregion #region 私有函数 /// <summary> /// 解析标记 /// </summary> /// <returns>语法高亮标记列表</returns> private List<SyntaxHighlightToken> ParseTokens() { List<SyntaxHighlightToken> tokens = new List<SyntaxHighlightToken>(); // 搜索标记 DocumentRange[] ranges = _document.FindAll("\"", SearchOptions.None); for (int i = 0; i < ranges.Length / 2; i++) { tokens.Add(new SyntaxHighlightToken(ranges[i * 2].Start.ToInt(), ranges[i * 2 + 1].Start.ToInt() - ranges[i * 2].Start.ToInt() + 1, _stringSettings)); } // 搜索关键词 foreach (var t in _keywords) { ranges = _document.FindAll(t, SearchOptions.None); foreach (var t1 in ranges) { if (!IsRangeInTokens(t1, tokens)) tokens.Add(new SyntaxHighlightToken(t1.Start.ToInt(), t1.Length, _keywordSettings)); } } // 排序 tokens.Sort(new SyntaxHighlightTokenComparer()); // 添加 AddPlainTextTokens(tokens); return tokens; } /// <summary> /// 添加明文标记 /// </summary> /// <param name="tokens">标记列表</param> private void AddPlainTextTokens(List<SyntaxHighlightToken> tokens) { int count = tokens.Count; if (count == 0) { tokens.Add(new SyntaxHighlightToken(0, _document.Range.End.ToInt(), _defaultSettings)); return; } tokens.Insert(0, new SyntaxHighlightToken(0, tokens[0].Start, _defaultSettings)); for (int i = 1; i < count; i++) { tokens.Insert(i * 2, new SyntaxHighlightToken(tokens[i * 2 - 1].End, tokens[i * 2].Start - tokens[i * 2 - 1].End, _defaultSettings)); } tokens.Add(new SyntaxHighlightToken(tokens[count * 2 - 1].End, _document.Range.End.ToInt() - tokens[count * 2 - 1].End, _defaultSettings)); } /// <summary> /// 是否在DocumentRange范围内 /// </summary> /// <param name="range">DocumentRange范围</param> /// <param name="tokens">标记</param> /// <returns></returns> private bool IsRangeInTokens(DocumentRange range, List<SyntaxHighlightToken> tokens) { foreach (var t in tokens) { if (range.Start.ToInt() >= t.Start && range.End.ToInt() <= t.End) return true; } return false; } #endregion } #region 比较器 public class SyntaxHighlightTokenComparer : IComparer<SyntaxHighlightToken> { public int Compare(SyntaxHighlightToken x, SyntaxHighlightToken y) { if (x == null || y == null) return 0; return x.Start - y.Start; } } #endregion }
调用方式:
richEditControl1.ReplaceService<ISyntaxHighlightService>(new CustomSyntaxHighlightService(richEditControl1.Document)); richEditControl1.LoadDocument(fileName, DevExpress.XtraRichEdit.DocumentFormat.PlainText);