WPF RichTextBox:在运行时用 UI 控件替换文本

发布于 2024-09-08 06:12:57 字数 245 浏览 0 评论 0原文

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

我以前有过使用 WPF 的 RichTextBox 的经验,并且了解 TextPointerTextContent 的概念。

我只是想知道:如何用 UI 控件替换 TextRange

I need to develop a messenger-like text box where certain tokens are being replaced with UI controls.
Just for example, if the user types :-), it should be replaced with a smiley image.

I have previous experience with WPF's RichTextBox, and I understand the concept of TextPointer and TextContent.

I just want to know: how can I replace a TextRange with a UI control?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

趁年轻赶紧闹 2024-09-15 06:12:57

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

    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;

        }
    }

Just figured out how to do it :-)
Enjoy!

    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;

        }
    }
轮廓§ 2024-09-15 06:12:57

这是另一个选项(语法格式化程序是我的,根据您的语法实现您自己的):

    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;
                }
            }
        }

Here is another option (the syntax formatter is mine, implement your own according to your syntax):

    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;
                }
            }
        }
厌味 2024-09-15 06:12:57

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

...
...

        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;                
        }


    }

玩得开心!,如果您有意见,请留下您的评论。

-吉利

Sorry, forgot the method's last section: :-)

...
...

        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;                
        }


    }

Have fun!, leave your comments if you have ones.

-Gili

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文