1 votes

WPF RichTextBox : Remplacer le texte par des contrôles UI au moment de l'exécution

J'ai besoin de développer une boîte de texte de type messager, où certains jetons sont remplacés par des contrôles d'interface utilisateur. Par exemple, si l'utilisateur tape :-), il doit être remplacé par une image de smiley.

J'ai une expérience préalable de la RichTextBox de WPF et je comprends le concept de TextPointer et de TextContent. Je ne sais simplement pas comment remplacer une TextRange par un contrôle UI...

J'apprécierais énormément votre aide :-) !

Gili

3voto

Gili Points 71

Je viens de trouver comment faire :-) Bon appétit !

    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;

        }
    }

1voto

Gili Points 71

Voici une autre option (le formateur de syntaxe est le mien, implémentez le vôtre en fonction de votre syntaxe) :

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

1voto

Gili Points 71

Désolé, j'ai oublié la dernière partie de la méthode : :-)

... ...

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

    }

Amusez-vous bien, laissez vos commentaires si vous en avez.

-Gili

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X