133 votes

Colorier différentes parties d'une chaîne RichTextBox

J'essaie de colorer des parties d'une chaîne de caractères à ajouter à un RichTextBox. J'ai une chaîne construite à partir de différentes chaînes de caractères.

string temp = "[" + DateTime.Now.ToShortTimeString() + "] " +
              userid + " " + message + Environment.NewLine;

Voici à quoi ressemblerait le message une fois qu'il sera construit.

[21:23] Utilisateur : mon message ici.

Je veux que tout ce qui se trouve entre les crochets [9:23] soit d'une couleur, que 'user' soit d'une autre couleur et que le message soit d'une autre couleur. J'aimerais ensuite que la chaîne soit ajoutée à ma RichTextBox.

Comment puis-je y parvenir ?

1 votes

6 votes

J'ai fait des recherches et je n'ai rien trouvé d'utile.

0 votes

Merci pour cette solution simple, qui fonctionne bien pour moi. N'oubliez pas d'utiliser la fonction AppendText(...) chaque fois que vous voulez ajouter du texte, et non l'opérateur '+=', sinon les couleurs appliquées ne seront pas prises en compte.

281voto

Nathan Baulch Points 7994

Voici une méthode d'extension qui surcharge la fonction AppendText avec un paramètre de couleur :

public static class RichTextBoxExtensions
{
    public static void AppendText(this RichTextBox box, string text, Color color)
    {
        box.SelectionStart = box.TextLength;
        box.SelectionLength = 0;

        box.SelectionColor = color;
        box.AppendText(text);
        box.SelectionColor = box.ForeColor;
    }
}

Et voici comment vous l'utiliseriez :

var userid = "USER0001";
var message = "Access denied";
var box = new RichTextBox
              {
                  Dock = DockStyle.Fill,
                  Font = new Font("Courier New", 10)
              };

box.AppendText("[" + DateTime.Now.ToShortTimeString() + "]", Color.Red);
box.AppendText(" ");
box.AppendText(userid, Color.Green);
box.AppendText(": ");
box.AppendText(message, Color.Blue);
box.AppendText(Environment.NewLine);

new Form {Controls = {box}}.ShowDialog();

Notez que vous pouvez remarquer un certain scintillement si vous produisez beaucoup de messages. Voir ce coin C# pour trouver des idées sur la façon de réduire le scintillement des RichTextBox.

6 votes

J'ai eu quelques problèmes avec ça. J'ai utilisé dans un autre endroit box.Text += mystring et ainsi toutes les couleurs ont disparu. Lorsque je l'ai remplacé par box.AppendText(mystring) ça a marché comme un charme.

3 votes

J'ai quelques problèmes avec le code, la couleur disparaît lors de l'ajout de la chaîne de caractères dans une autre couleur, la seule différence étant que j'assigne var box à une richtextbox.... déjà créée.

1 votes

Qu'est-ce que je fais mal... "SelectionStart" n'est pas une propriété d'une RichTextBox (ou du moins je ne peux pas y accéder) ? J'ai trouvé "Selection" mais c'est une propriété get-only...

14voto

tedebus Points 346

Il s'agit de la version modifiée que j'ai intégrée à mon code (j'utilise .Net 4.5) mais je pense que cela devrait également fonctionner avec la version 4.0.

public void AppendText(string text, Color color, bool addNewLine = false)
{
        box.SuspendLayout();
        box.SelectionColor = color;
        box.AppendText(addNewLine
            ? $"{text}{Environment.NewLine}"
            : text);
        box.ScrollToCaret();
        box.ResumeLayout();
}

Différences avec l'original :

  • possibilité d'ajouter du texte à une nouvelle ligne ou de l'annexer simplement
  • pas besoin de changer la sélection, cela fonctionne de la même manière
  • inséré ScrollToCaret pour forcer l'autoscroll
  • ajout d'appels de suspension/reprise de la mise en page

13voto

Renan F. Points 145

J'ai développé la méthode avec la police comme paramètre :

public static void AppendText(this RichTextBox box, string text, Color color, Font font)
{
    box.SelectionStart = box.TextLength;
    box.SelectionLength = 0;

    box.SelectionColor = color;
    box.SelectionFont = font;
    box.AppendText(text);
    box.SelectionColor = box.ForeColor;
}

7voto

Elo Points 1096

Je pense que modifier un "texte sélectionné" dans une RichTextBox n'est pas la bonne façon d'ajouter du texte coloré. Voici donc une méthode pour ajouter un "bloc de couleur" :

        Run run = new Run("This is my text");
        run.Foreground = new SolidColorBrush(Colors.Red); // My Color
        Paragraph paragraph = new Paragraph(run);
        MyRichTextBlock.Document.Blocks.Add(paragraph);

De MSDN :

La propriété Blocks est la propriété de contenu de RichTextBox. Il s'agit d'une collection d'éléments Paragraphe. Le contenu de chaque élément Paragraphe peut contenir les éléments suivants :

  • En ligne

  • InlineUIContainer

  • Exécuter

  • Portée

  • Gras

  • Hyperlien

  • Italique

  • Souligner

  • LineBreak

Je pense donc que vous devez diviser votre chaîne en fonction de la couleur des pièces, et créer autant d'éléments que possible. Run les objets, si nécessaire.

2voto

Cela fonctionne pour moi ! J'espère qu'il vous sera utile !

public static RichTextBox RichTextBoxChangeWordColor(ref RichTextBox rtb, string startWord, string endWord, Color color)
{
    rtb.SuspendLayout();
    Point scroll = rtb.AutoScrollOffset;
    int slct = rtb.SelectionIndent;
    int ss = rtb.SelectionStart;
    List<Point> ls = GetAllWordsIndecesBetween(rtb.Text, startWord, endWord, true);
    foreach (var item in ls)
    {
        rtb.SelectionStart = item.X;
        rtb.SelectionLength = item.Y - item.X;
        rtb.SelectionColor = color;
    }
    rtb.SelectionStart = ss;
    rtb.SelectionIndent = slct;
    rtb.AutoScrollOffset = scroll;
    rtb.ResumeLayout(true);
    return rtb;
}

public static List<Point> GetAllWordsIndecesBetween(string intoText, string fromThis, string toThis,bool withSigns = true)
{
    List<Point> result = new List<Point>();
    Stack<int> stack = new Stack<int>();
    bool start = false;
    for (int i = 0; i < intoText.Length; i++)
    {
        string ssubstr = intoText.Substring(i);
        if (ssubstr.StartsWith(fromThis) && ((fromThis == toThis && !start) || !ssubstr.StartsWith(toThis)))
        {
            if (!withSigns) i += fromThis.Length;
            start = true;
            stack.Push(i);
        }
        else if (ssubstr.StartsWith(toThis) )
        {
            if (withSigns) i += toThis.Length;
            start = false;
            if (stack.Count > 0)
            {
                int startindex = stack.Pop();
                result.Add(new Point(startindex,i));
            }
        }
    }
    return result;
}

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