简体   繁体   English

在richtextbox wpf中更改特定文本的颜色

[英]Change back color of specific text in richtextbox wpf

I am working on function, that will change back color of tags in text of RichTextBox (blah blah blah < i>This will be changed< /i> blah blah blah). 我正在研究函数,它将改变RichTextBox文本中标签的颜色(等等等等)。 I tried to make some code, but it is highlighting correctly only first tag. 我尝试编写一些代码,但仅第一个标记正确突出显示。 The second tag will be highlited a few chars before. 第二个标签将被高亮几个字符。 Please, how could I get this work? 拜托,我该怎么做呢?

Actual state - Function colorize correctly only first tag, others are colored characters before. 实际状态-函数仅第一个标签正确着色,其他字符之前为彩色字符。

State I want - Have colored only tags and it's content in RichTextBox. 我想要的状态-仅对标记着色,并且其内容在RichTextBox中。

Problem part: 问题部分:

        TextPointer text = txbPlainText.Document.ContentStart;
        while (text.GetPointerContext(LogicalDirection.Forward) != TextPointerContext.Text)
        {
          text = text.GetNextContextPosition(LogicalDirection.Forward);
        }
        TextPointer start = text.GetPositionAtOffset(tagStartIndex);
        TextPointer end = text.GetPositionAtOffset(i + tagBuilder.Length);

        TextRange textRange = new TextRange(start, end);
        textRange.ApplyPropertyValue(TextElement.BackgroundProperty, new SolidColorBrush(Color.FromRgb(220, 204, 163)));

How it looks like: Image with problem 外观: 有问题的图片

This is whole function: 这是整个功能:

private void ColorizeTags()
{
  string tagString = string.Empty;
  int tagStartIndex = 0;
  char[] txbChars = GetTxbText().ToCharArray();

  for (int i = 0; i < txbChars.Count(); i++)
  {
    char actualChar = txbChars[i];

    if (actualChar == '<' && txbChars[i + 1] != '/')
    {
      StringBuilder tagBuilder = new StringBuilder();
      foreach (string tag in TagList)
      {
        for (int x = i; x < (i + tag.Length); x++)
        {
          if (x > txbChars.Count())
          {
            break;
          }

          tagBuilder.Append(txbChars[x]);
        }

        if (tagBuilder.ToString() == tag)
        {
          tagString = tagBuilder.ToString();
          tagStartIndex = i;
          break;
        }
      }
    }
    else if (actualChar == '<' && txbChars[i + 1] == '/')
    {
      if (string.IsNullOrWhiteSpace(tagString))
      {
        continue;
      }

      string endTag = tagString.Insert(tagString.IndexOf('<') + 1, "/");
      StringBuilder tagBuilder = new StringBuilder();

      for (int c = i; c < (i + endTag.Length); c++)
      {
        tagBuilder.Append(txbChars[c]);
      }

      if (tagBuilder.ToString() == endTag)
      {
        TextPointer text = txbPlainText.Document.ContentStart;
        while (text.GetPointerContext(LogicalDirection.Forward) != TextPointerContext.Text)
        {
          text = text.GetNextContextPosition(LogicalDirection.Forward);
        }
        TextPointer start = text.GetPositionAtOffset(tagStartIndex);
        TextPointer end = text.GetPositionAtOffset(i + tagBuilder.Length);

        TextRange textRange = new TextRange(start, end);
        textRange.ApplyPropertyValue(TextElement.BackgroundProperty, new SolidColorBrush(Color.FromRgb(220, 204, 163)));
        tagString = string.Empty;
        continue;
      }
    }
  }
}

private string GetTxbText()
{
  return new TextRange(txbPlainText.Document.ContentStart, txbPlainText.Document.ContentEnd).Text;
}

I searched and found the problem. 我搜索并发现了问题。 The thing is when I was getting the position offset of the start and the end, value of the current textpointer has changed. 问题是当我获得起点和终点的位置偏移时,当前文本指针的值已更改。

And second problem was, that my TextPointer text ignored whitespaces, solution below. 第二个问题是,我的TextPointer text忽略了空格,以下为解决方案。

Solution: Don't get position offset straightly. 解决方案:不要使位置直线偏移。

Before: 之前:

...
TextPointer text = txbPlainText.Document.ContentStart;
while (text.GetPointerContext(LogicalDirection.Forward) != TextPointerContext.Text)
{
  text = text.GetNextContextPosition(LogicalDirection.Forward);
}
TextPointer start = text.GetPositionAtOffset(tagStartIndex);
TextPointer end = text.GetPositionAtOffset(i + tagBuilder.Length);
...

After: 后:

...
TextPointer text = txbPlainText.Document.ContentStart;
TextPointer start = GetTextPointAt(text, tagStartIndex);
TextPointer end = GetTextPointAt(text, endIndex);
...

private static TextPointer GetTextPointAt(TextPointer from, int pos)
{
  TextPointer ret = from;
  int i = 0;

  while ((i < pos) && (ret != null))
  {
    if ((ret.GetPointerContext(LogicalDirection.Backward) == TextPointerContext.Text) || (ret.GetPointerContext(LogicalDirection.Backward) == TextPointerContext.None))
      i++;

    if (ret.GetPositionAtOffset(1, LogicalDirection.Forward) == null)
      return ret;

    ret = ret.GetPositionAtOffset(1, LogicalDirection.Forward);
  }

  return ret;
}

Source of answer 答案来源

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM