我有一個來自舊的第 3 方系統的代碼文本檔案,我正在嘗試升級。該代碼是結構化文本,看起來與 VB 非常相似。我想決議文本檔案并在 WPF 應用程式中顯示格式化文本。理想情況下,它看起來類似于 Visual Studio 代碼編輯器。
下面是我嘗試格式化的代碼示例
--this is a comment
LOCAL tag1 --LOCAL would be formatted
LOCAL tag2
LOCAL foo
IF tag1 > tag2 THEN --IF and THEN would be formatted
foo = tag1
END IF --end if would be formatted
我已經設法通過從代碼的原始文本創建 FlowDocument 來做到這一點。然后我在文本檔案中搜索關鍵字并使用以下方法更改文本顏色
private FlowDocument FormatDocument(FlowDocument flowDocument, List<string> keyWordList, Brush brush)
{
TextPointer position = flowDocument.ContentStart;
while (position != null)
{
if (position.CompareTo(flowDocument.ContentEnd) == 0)
break;
if (position.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.Text) //checks to see if textpointer is actually text
{
foreach (string keyword in keyWordList)
{
string textRun = position.GetTextInRun(LogicalDirection.Forward);
string pattern = @"\b" Regex.Escape(keyword) @"\b";
Match match = Regex.Match(textRun, pattern, RegexOptions.IgnoreCase);
if (match.Success)
{
int indexInRun = match.Index;
int indexOfComment = textRun.IndexOf("--");
TextPointer startPosition = position.GetPositionAtOffset(indexInRun);
TextPointer endPosition = startPosition.GetPositionAtOffset(keyword.Length);
TextRange keywordRange = new TextRange(startPosition, endPosition);
string test = keywordRange.Text;
if (indexOfComment == -1 || indexInRun < indexOfComment)
keywordRange.ApplyPropertyValue(TextElement.ForegroundProperty, brush);
}
}
position = position.GetNextContextPosition(LogicalDirection.Forward);
}
else //If the current position doesn't represent a text context position, go to the next context position.
position = position.GetNextContextPosition(LogicalDirection.Forward); // This can effectively ignore the formatting or embed element symbols.
}
return flowDocument;
}
當檔案很大時代碼有點慢所以我想知道有沒有更好的方法來解決這個問題?
uj5u.com熱心網友回復:
您的代碼似乎沒問題,只是您在每個回圈的每次迭代中都創建了一堆物件,這會很慢,尤其是對于 Regex 物件。如果你編譯它們,正則運算式也會快得多。在任一回圈之外創建您的 Regex 物件并編譯它們,我敢打賭您會看到一些改進。
如果這還不夠改進,請嘗試構建一個匹配關鍵字串列中的任何單詞的單個正則運算式 (\b[keyword1|keyword2|keyword3|...]\b)。
public static FlowDocument FormatDocument(FlowDocument flowDocument,
List<string> keyWordList,
Brush brush)
{
var regexForKeyword = keyWordList.ToDictionary(k => k,
k => new Regex(@"\b" Regex.Escape(keyword) @"\b",
RegexOptions.Compiled | RegexOptions.IgnoreCase));
var position = flowDocument.ContentStart;
while (position != null)
{
if (position.CompareTo(flowDocument.ContentEnd) == 0)
break;
if (position.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.Text) //checks to see if textpointer is actually text
{
foreach (string keyword in keyWordList)
{
var textRun = position.GetTextInRun(LogicalDirection.Forward);
var match = regexForKeyword[keyword].Match(textRun);
if (match.Success)
{
var indexInRun = match.Index;
var indexOfComment = textRun.IndexOf("--");
var startPosition = position.GetPositionAtOffset(indexInRun);
var endPosition = startPosition.GetPositionAtOffset(keyword.Length);
var keywordRange = new TextRange(startPosition, endPosition);
var test = keywordRange.Text;
if (indexOfComment == -1 || indexInRun < indexOfComment)
keywordRange.ApplyPropertyValue(TextElement.ForegroundProperty, brush);
}
}
position = position.GetNextContextPosition(LogicalDirection.Forward);
}
else //If the current position doesn't represent a text context position, go to the next context position.
position = position.GetNextContextPosition(LogicalDirection.Forward); // This can effectively ignore the formatting or embed element symbols.
}
return flowDocument;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/452448.html
上一篇:如何“禁用”WPF用戶控制元件?
下一篇:<EventTriggerRoutedEvent="Binding.TargetUpdated">未使用ContentTemplateSelector觸發
