web-dev-qa-db-fra.com

Plusieurs couleurs dans une étiquette C # .NET

Je cherche un moyen d’afficher plusieurs couleurs dans une seule étiquette C #/.NET. Par exemple, l'étiquette affiche une série de valeurs séparées par csv qui prennent chacune une couleur en fonction du compartiment dans lequel elles se trouvent. Je préférerais ne pas utiliser plusieurs étiquettes, car les valeurs sont de longueur variable et je ne veux pas jouer avec les mises en page dynamiques. Existe-t-il un support natif pour cela?

34
Cory

Il n'y a pas de contrôle natif dans .NET qui le fasse. Votre meilleur pari est d'écrire votre propre UserControl (appelez-le RainbowLabel ou quelque chose du genre). Normalement, un contrôle d'étiquette personnalisé hériterait directement de Label, mais comme vous ne pouvez pas obtenir du texte multicolore dans une étiquette, vous héritez simplement de UserControl.

Pour rendre le texte, votre UserControl peut scinder le texte en virgules, puis charger dynamiquement une étiquette de couleur différente pour chaque morceau. Un meilleur moyen, cependant, serait de rendre le texte directement sur votre UserControl à l'aide des méthodes DrawString et MeasureString dans l'espace de noms Graphics.

Écrire UserControls dans .NET n’est vraiment pas difficile, et ce genre de problème inhabituel est exactement ce à quoi servent les UserControls personnalisés.

Mise à jour : voici une méthode simple que vous pouvez utiliser pour restituer le texte multicolore sur un PictureBox:

public void RenderRainbowText(string Text, PictureBox pb)
{
    // PictureBox needs an image to draw on
    pb.Image = new Bitmap(pb.Width, pb.Height);
    using (Graphics g = Graphics.FromImage(pb.Image))
    {
        // create all-white background for drawing
        SolidBrush brush = new SolidBrush(Color.White);
        g.FillRectangle(brush, 0, 0,
            pb.Image.Width, pb.Image.Height);
        // draw comma-delimited elements in multiple colors
        string[] chunks = Text.Split(',');
        brush = new SolidBrush(Color.Black);
        SolidBrush[] brushes = new SolidBrush[] { 
            new SolidBrush(Color.Red),
            new SolidBrush(Color.Green),
            new SolidBrush(Color.Blue),
            new SolidBrush(Color.Purple) };
        float x = 0;
        for (int i = 0; i < chunks.Length; i++)
        {
            // draw text in whatever color
            g.DrawString(chunks[i], pb.Font, brushes[i], x, 0);
            // measure text and advance x
            x += (g.MeasureString(chunks[i], pb.Font)).Width;
            // draw the comma back in, in black
            if (i < (chunks.Length - 1))
            {
                g.DrawString(",", pb.Font, brush, x, 0);
                x += (g.MeasureString(",", pb.Font)).Width;
            }
        }
    }
}

Évidemment, cela cassera si vous avez plus de 4 éléments délimités par des virgules dans votre texte, mais vous avez l’idée. De plus, MeasureString semble présenter un petit problème qui lui fait redonner une largeur de quelques pixels plus large que nécessaire, de sorte que la chaîne multicolore semble étirée.

Il devrait être simple de modifier ce code pour un UserControl.

Note : TextRenderer est une meilleure classe à utiliser pour dessiner et mesurer des chaînes, car il utilise ints. Graphics.DrawString et .MeasureString utilisent des flottants. Vous obtiendrez ainsi des erreurs décalées par pixel ici et là.

Update : Forget à propos de l'utilisation de TextRenderer. C'est chien lent.

42
MusiGenesis

Vous pouvez essayer d’utiliser un RichTextBox afin d’obtenir plusieurs couleurs pour la chaîne, de la rendre en lecture seule et de supprimer la bordure. Changez la couleur d'arrière-plan pour qu'elle soit identique à celle du formulaire et vous pourriez vous en tirer.

14
Phil Wright

Au lieu de cela, vous pouvez le faire en tant que fichier RTF ou HTML dans un contrôle approprié (tel que WebBrowser). Cela prendrait probablement un peu plus de ressources que ce que vous aimeriez idéalement, mais cela fonctionnera assez rapidement.

4
Marc Gravell

Si vous construisez votre application Windows pour des personnes avec XP et plus, vous pouvez utiliser WPF. Même s'il s'agit d'une application Windows Forms, vous pouvez ajouter un UserControl WPF.

Je voudrais ensuite utiliser une étiquette et définir la propriété "Foreground" pour être un dégradé de couleurs.

Ou bien, dans Windows Forms (pas de WPF), vous pouvez simplement utiliser un "Panneau de flux", puis dans une boucle for, ajoutez plusieurs étiquettes en tant que segments de votre phrase ... Elles "couleront" ensemble comme s'il s'agissait d'une étiquette. .

4
Timothy Khouri

Légèrement hors sujet ... Vous pouvez aussi vérifier: 

1
Yordan Georgiev

J'utilise assez souvent des étiquettes de couleur pour marquer les mots-clés en rouge, etc. etc. Comme dans sa réponse, j'utilise un contrôle RichTextBox, supprime la bordure et définit la couleur d'arrière-plan sur SystemColors.Control.

Pour écrire du texte en couleur, le contrôle est d'abord effacé, puis j'utilise cette fonction pour ajouter du texte en couleur:

private void rtb_AppendText(Font selfont, Color color, Color bcolor, 
                        string text, RichTextBox box)
    {
            // append the text to the RichTextBox control
            int start = box.TextLength;
            box.AppendText(text);
            int end = box.TextLength;

            // select the new text
            box.Select(start, end - start);
            // set the attributes of the new text
            box.SelectionColor = color;
            box.SelectionFont = selfont;
            box.SelectionBackColor = bcolor;
            // unselect
            box.Select(end, 0);

            // only required for multi line text to scroll to the end
            box.ScrollToCaret();
    }

Si vous souhaitez exécuter cette fonction avec "mono", ajoutez un espace avant chaque nouveau texte coloré. Sinon, mono ne définira pas la nouvelle couleur correctement. Ce n'est pas nécessaire avec .NET

Usage:

myRtb.Text = "";
rtb_AppendText(new Font("Courier New", (float)10), 
                   Color.Red, SystemColors.Control, " my red text", myRtb);
rtb_AppendText(new Font("Courier New", (float)10), 
                   Color.Blue, SystemColors.Control, " followed by blue", myRtb);
0
harry4516

Essaye ça, 

   labelId.Text = "Successfully sent to" + "<a style='color:Blue'> "  + name + "</a>"; 
0
Padmaja Vudatha

Vous pouvez simplement utiliser plusieurs étiquettes. Définissez les propriétés de police souhaitées, puis utilisez la gauche. top et width pour afficher les mots que vous souhaitez afficher différemment. Cela suppose que vous utilisez des formulaires Windows.

0
Chris Wegener