【问题标题】:WPF RichTextBox: Replace text with UI controls @ run timeWPF RichTextBox:用 UI 控件@运行时替换文本
【发布时间】:2010-07-03 13:58:18
【问题描述】:

我需要开发一个类似信使的文本框,其中某些标记被 UI 控件替换。 举个例子,如果用户输入:-),它应该被替换为笑脸图像。

之前有使用WPF的RichTextBox的经验,了解TextPointerTextContent的概念。

我只想知道:如何将TextRange 替换为 UI 控件?

【问题讨论】:

    标签: wpf richtextbox


    【解决方案1】:

    刚刚知道怎么做 :-) 尽情享受吧!

        public static void ReplaceTextRangeWithUIControl(this RichTextBox textBox, TextRange textRange)
        {                                   
            if (textRange.Start.Parent is Run)
            {
                var run = textRange.Start.Parent as Run;
    
                var runBefore =
                    new Run(new TextRange(run.ContentStart,textRange.Start).Text);
                var runAfter =
                    new Run(new TextRange(textRange.End,run.ContentEnd).Text);
    
    
                textRange.Start.Paragraph.Inlines.Add(runBefore);
                textRange.Start.Paragraph.Inlines.Add(new TextBlock() { Background = Brushes.Green, Text = textRange.Text });
                textRange.Start.Paragraph.Inlines.Add(runAfter);
                textRange.Start.Paragraph.Inlines.Remove(run);
    
                textBox.CaretPosition = runAfter.ContentEnd;
    
            }
        }
    

    【讨论】:

      【解决方案2】:

      这里还有一个选项(语法格式化器是我的,根据你的语法实现你自己的):

          private void ReplaceTokensWithControl(Run run)
          {
              var text = run.Text;
      
              bool inToken = false;
              var startIndex = 0;
              var endIndex = 0;
              for (var i = 0; i < text.Length; i++)
              {
                  if (Char.IsWhiteSpace(text[i]) | SyntaxFormatter.TextControlSpecialTokens.Contains(text[i]))
                  {
                      if (i > 0 && !(Char.IsWhiteSpace(text[i - 1]) | SyntaxFormatter.TextControlSpecialTokens.Contains(text[i - 1])))
                      {
                          endIndex = i - 1;
                          string token = text.Substring(startIndex, endIndex - startIndex + 1);
      
                          string tokenContext = text.Substring(0, startIndex);
                          if (SyntaxFormatter.IsTextControlToken(token, tokenContext))
                          {
                              var textBefore = run.Text.Substring(0, startIndex);
                              var runBefore = new Run(textBefore);
                              run.ContentStart.Paragraph.Inlines.InsertBefore(run, runBefore);
      
                              Run runAfter = null;
                              if (endIndex + 1 < run.Text.Length)
                              {
                                  var textAfter = run.Text.Substring(endIndex + 1, run.Text.Length - (endIndex + 1));
                                  runAfter = new Run(textAfter);
                                  run.ContentStart.Paragraph.Inlines.InsertAfter(runBefore, runAfter);
                              }
      
                              runBefore.ContentStart
                                  .Paragraph
                                  .Inlines
                                  .InsertAfter(runBefore,new InlineUIContainer(SyntaxFormatter.GetTokenTextControl(text, tokenContext)));
      
                              run.ContentStart.Paragraph.Inlines.Remove(run);                                                
      
                              if (runAfter != null)
                                  ReplaceTokensWithControl(runAfter);
      
                              return;
                          }
                      }
                  }
                  else
                  {
                      if (!inToken)
                      {
                          inToken = true;
                          startIndex = i;
                      }
                  }
              }
      

      【讨论】:

        【解决方案3】:

        抱歉,忘记了方法的最后一部分::-)

        ... ...

                var lastWord = text.Substring(startIndex, text.Length - startIndex);
                if (SyntaxFormatter.IsTextToken(lastWord))
                {
                    var tag = new SyntaxTokenProperties();
                    tag.StartPosition = run.ContentStart.GetPositionAtOffset(startIndex, LogicalDirection.Forward);
                    tag.EndPosition = run.ContentStart.GetPositionAtOffset(endIndex + 1, LogicalDirection.Backward);
                    tag.Word = lastWord;                
                }
        
        
            }
        

        玩得开心!如果有,请留下您的 cmets。

        -吉利

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-11-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-11-24
          • 1970-01-01
          相关资源
          最近更新 更多