【问题标题】:How to select RichTextBox text given an index and length如何在给定索引和长度的情况下选择 RichTextBox 文本
【发布时间】:2012-08-17 10:24:09
【问题描述】:

如果只给你一个特定文本的索引和长度(或 EndIndex)来选择,你如何在 WPF 版本的 RichTextBox 中执行此操作?

这在 Textbox 中非常可行,因为您可以调用 Textbox.Select(startIndex,Length) 但我在 RTB 中看不到任何等效项。

编辑:我找到了选择的答案

internal string Select(RichTextBox rtb, int index, int length)
        {
            TextRange textRange = new TextRange(rtb.Document.ContentStart, rtb.Document.ContentEnd);

            if (textRange.Text.Length >= (index + length))
            {
                TextPointer start = textRange.Start.GetPositionAtOffset(index, LogicalDirection.Forward);
                TextPointer end = textRange.Start.GetPositionAtOffset(index + length, LogicalDirection.Backward);
                rtb.Selection.Select(start, end);
            }
            return rtb.Selection.Text;
        } 

但是,当我尝试在选择后突出显示该行时:

rtb.Selection.ApplyPropertyValue(TextElement.BackgroundProperty, new SolidColorBrush(Colors.LightBlue));

突出显示功能仅在第一次尝试时有效,在第二次尝试后中断。有人知道这是什么原因吗?

【问题讨论】:

    标签: c# .net wpf richtextbox


    【解决方案1】:

    好的,这个问题很老,但我终于找到了答案,所以我把它放在这里。

    当我尝试使用 RichTextBox 制作一些 Syntaxhighlighter 时,我遇到了类似的问题。 我发现,当你使用 ApplyPropertyValue 玩 arround 时,你不能再简单地使用 GetPositionAtOffset 了。我相信应用 propertyvalues 似乎改变了 TextTokens 在 Document 中的“内部位置”,因此“制动”了这个功能。

    解决方法:

    每次您需要使用 GetPositionAtOffset 时,首先在 Document 的完整 TextRange 上调用 ClearAllProperties,然后使用 ApplyPropertyValue 重新应用所有属性,但是这次从右到左。 (右表示最高偏移)

    我不知道您是否应用了任何 PropertyValues 期望选择突出显示,因此您可能需要在其中投入更多思考。

    这是导致问题时我的代码的外观:

        private void _highlightTokens(FlowDocument document)
        {
            TextRange fullRange = new TextRange(document.ContentStart, document.ContentEnd);
            foreach (Token token in _tokenizer.GetTokens(fullRange.Text))
            {
                TextPointer start = fullRange.Start.GetPositionAtOffset(token.Position);
                TextPointer end = start.GetPositionAtOffset(token.Length);
    
                TextRange range = new TextRange(start, end);
                range.ApplyPropertyValue(TextElement.ForegroundProperty, _getTokenColor(token));
            }
        }
    

    我这样修复它:

        private void _highlightTokens(FlowDocument document)
        {
            TextRange fullRange = new TextRange(document.ContentStart, document.ContentEnd);
            fullRange.ClearAllProperties(); // NOTICE: first remove allProperties.
            foreach (Token token in _tokenizer.GetTokens(fullRange.Text).Reverse()) // NOTICE: Reverse() to make the "right to left" work
            {
                TextPointer start = fullRange.Start.GetPositionAtOffset(token.Position);
                TextPointer end = start.GetPositionAtOffset(token.Length);
    
                TextRange range = new TextRange(start, end);
                range.ApplyPropertyValue(TextElement.ForegroundProperty, _getTokenColor(token));
            }
        }
    

    【讨论】:

      【解决方案2】:

      RichTextBox.Selection 属性使用Select() 方法。

      【讨论】:

      • Select 方法接受两个文本指针,我只有一个索引和长度可以使用,它们都是整数。在这种情况下如何正确设置我的文本指针变量?
      【解决方案3】:

      Blockquote 你可以得到空格之间的文字.....

      私有字符串 RichWordOver(RichTextBox rch, int x, int y) {

              int pos = rch.GetCharIndexFromPosition(new Point(x, y));
              if (pos <= 0) return "";
      
      
              string txt = rch.Text;
      
              int start_pos;
              for (start_pos = pos; start_pos >= 0; start_pos--)
              {
      
                  char ch = txt[start_pos];
                  if (!char.IsLetterOrDigit(ch) && !(ch=='_')) break;
              }
              start_pos++;
              int end_pos;
              for (end_pos = pos; end_pos < txt.Length; end_pos++)
              {
                  char ch = txt[end_pos];
                  if (!char.IsLetterOrDigit(ch) && !(ch == '_')) break;
              }
              end_pos--;
      
      
              if (start_pos > end_pos) return "";
              return txt.Substring(start_pos, end_pos - start_pos + 1);
          }
      

      private void rchText_MouseClick(object sender, MouseEventArgs e) { MessageBox.Show(RichWordOver(rchText, e.X, e.Y)); }

      【讨论】:

        猜你喜欢
        • 2023-04-06
        • 2011-09-26
        • 2022-01-21
        • 2020-01-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-10-13
        相关资源
        最近更新 更多