【问题标题】:Selected Text Formatting in WPF RichTexBoxWPF RichTextBox 中的选定文本格式
【发布时间】:2020-04-17 06:04:43
【问题描述】:

我正在尝试在 WPF RichTextBox 中以编程方式选择(使用正则表达式)文本格式。用例只是一个 WPF RichTextBox,用户在其中键入文本。但是,为了提高或加速可读性,我想在输入文本时加入一些自动格式。

How to select text from the RichTextBox and then color it? 的以下代码正是我想要做的。但是,据我所知,此代码适用于 WinForms RichTextBox:

public void ColourRrbText(RichTextBox rtb)
{
    Regex regExp = new Regex(@"\b(For|Next|If|Then)\b");

    foreach (Match match in regExp.Matches(rtb.Text))
    {
        rtb.Select(match.Index, match.Length);
        rtb.SelectionColor = Color.Blue;
    }
}

我尝试将其转换如下:

public static void ColorSpecificText(RichTextBox rtb)
{
    TextRange textRange = new TextRange(rtb.Document.ContentEnd, rtb.Document.ContentEnd);

    Regex regex = new Regex(@"\b(For|Next|If|Then)\b");

    foreach (Match match in regex.Matches(textRange.Text))
    { 
        textRange.Select(match.Index, match.Length); // <--- DOESN'T WORK
        textRange.SelectionColor = Color.Blue; // <--- DOESN'T WORK
    }
}

但是,我被困在如何将“match.Index、match.Length”和“SelectionColor”语法转换为 WPF RichTextBox 知道如何处理的东西上。我搜索了其他帖子,但大多数似乎也是针对 WinForms RichTextBox,而不是 WPF。任何指导将不胜感激。

【问题讨论】:

  • 要使用单词边界,请使用逐字字符串文字,或双反斜杠,@"\b(For|Next|If|Then)\b"
  • 感谢@Wiktor。你是对的,需要@。但这并不能解决 match.index 的问题,匹配长度会产生错误代码“无法从 int 转换为 'System.Windows.Documents.TextPointer'”。
  • Thaty 已经不是正则表达式问题。请修改问题。 textRange.Select 期望什么类型的价值? SelectionColor 似乎期待 System.Drawing.Color。但这种可能性会影响整个组件文本,而不仅仅是其中的一部分。
  • 我同意 - 这不是正则表达式问题。 textRange.Select 取两个 TextPointers。我的问题是使用 TextPointers 指定 match.index 和 match.length 的语法是什么。
  • @scorpiotomse 如果某个答案解决了您的问题,请点击勾选标记让其他人知道此问题已解决。

标签: wpf formatting richtextbox


【解决方案1】:

这是语法:

TextRange textRange = new TextRange(rtb.Document.ContentStart, rtb.Document.ContentEnd);
textRange.ApplyPropertyValue(TextElement.ForegroundProperty, Brushes.Black);
Regex regex = new Regex(@"\b(For|Next|If|Then)\b");

int i = 0;
foreach (Match match in regex.Matches(textRange.Text))
{
    var wordStartOffset = textRange.Start.GetPositionAtOffset(i + match.Index);
    var wordEndOffset = textRange.Start.GetPositionAtOffset(i + match.Index + match.Length);
    var wordRange = new TextRange(wordStartOffset, wordEndOffset);
    wordRange.ApplyPropertyValue(TextElement.ForegroundProperty, Brushes.LightBlue);
    i += 4; // could be something else
}

尽管由于您的策略,它可能无法正确突出显示。恐怕字符串索引不足以创建正确的 TextPointer。 +4 用于跳过格式化开销,这就是为什么如果存在其他格式,它可能不起作用。

【讨论】:

  • 嗨@Bizhan:超级有帮助。有用。真的很感激。将深入您的代码以更好地理解。 “不足以创建正确的 TextPointer”是什么意思?正确的语法是什么?
  • @scorpiotomse,不客气。正确的方法主要取决于您的设计。 AFAIK,RTB 使用 FlowDocument 作为其内容,并且各种疯狂的东西都可以进入其中,因此很难说出在不同场景中需要多少偏移量。我对 RTB 了解不多,但对我来说最简单的处理方法是连续查找并应用每个单词,而不是查找所有然后应用所有。
  • @scorpiotomse 澄清一下,如果您删除此行 :ApplyPropertyValue(...black) 则不知道它是如何工作的。例如如果您已经有一些颜色或其他格式,则需要在某处记住这些偏移量并将其考虑在内。但除此之外,上面的代码按原样工作。您可以对其进行调试并查看元素是如何创建的,以便每次应用格式时偏移量都会移动 4
  • 好的 - 太好了 - 再次感谢。事实上,我确实同意每次都初始化格式 - 所以 ApplyPropertyValue (... black) 完全没问题。
猜你喜欢
  • 1970-01-01
  • 2011-05-14
  • 2014-11-02
  • 1970-01-01
  • 2010-09-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多