Question

Est-il possible de formater certains textes dans une étiquette WinForm au lieu de diviser le texte en plusieurs étiquettes ?Veuillez ne pas tenir compte des balises HTML dans le texte de l'étiquette ;c'est seulement utilisé pour faire valoir mon point de vue.

Par exemple:

Dim myLabel As New Label
myLabel.Text = "This is <b>bold</b> text.  This is <i>italicized</i> text."

Ce qui produirait le texte dans l'étiquette comme :

C'est audacieux texte.C'est en italique texte.

Était-ce utile?

La solution

Ce n'est pas possible avec une étiquette WinForms telle qu'elle est.L’étiquette doit avoir exactement une police, avec exactement une taille et une seule face.Vous avez plusieurs options:

  1. Utiliser des étiquettes distinctes
  2. Créez une nouvelle classe dérivée de Control qui effectue son propre dessin via GDI+ et utilisez-la à la place de Label ;c'est probablement votre meilleure option, car elle vous donne un contrôle total sur la manière de demander au contrôle de formater son texte
  3. Utilisez un contrôle d'étiquette tiers qui vous permettra d'insérer des extraits HTML (il y en a beaucoup - vérifiez CodeProject) ;ce serait l’implémentation du n°2 par quelqu’un d’autre.

Autres conseils

Pas vraiment, mais vous pouvez faire semblant avec une RichTextBox en lecture seule sans bordures.RichTextBox prend en charge le format de texte enrichi (rtf).

Une autre solution de contournement, en retard à la fête :si vous ne souhaitez pas utiliser de contrôle tiers et que vous cherchez simplement à attirer l'attention sur une partie du texte de votre étiquette, et tu es d'accord avec les soulignements, tu peux utiliser un LienÉtiquette.

Notez que beaucoup considèrent cela comme un «crime d'utilisabilité", mais si vous ne concevez pas quelque chose pour la consommation de l'utilisateur final, c'est peut-être quelque chose que vous êtes prêt à avoir sur la conscience.

L'astuce consiste à ajouter des liens désactivés aux parties de votre texte que vous souhaitez souligner, puis à définir globalement les couleurs des liens pour qu'elles correspondent au reste de l'étiquette.Vous pouvez définir presque toutes les propriétés nécessaires au moment de la conception, à l'exception des Links.Add() morceau, mais les voici dans le code :

linkLabel1.Text = "You are accessing a government system, and all activity " +
                  "will be logged.  If you do not wish to continue, log out now.";
linkLabel1.AutoSize = false;
linkLabel1.Size = new Size(365, 50);
linkLabel1.TextAlign = ContentAlignment.MiddleCenter;
linkLabel1.Links.Clear();
linkLabel1.Links.Add(20, 17).Enabled = false;   // "government system"
linkLabel1.Links.Add(105, 11).Enabled = false;  // "log out now"
linkLabel1.LinkColor = linkLabel1.ForeColor;
linkLabel1.DisabledLinkColor = linkLabel1.ForeColor;

Résultat:

enter image description here

Solution qui a fonctionné pour moi - en utilisant RichEditBox personnalisé.Avec les bonnes propriétés, il ressemblera à une simple étiquette avec un support audacieux.

1) Tout d’abord, ajoutez votre classe RichTextLabel personnalisée avec le curseur désactivé :

public class RichTextLabel : RichTextBox
{
    public RichTextLabel()
    {
        base.ReadOnly = true;
        base.BorderStyle = BorderStyle.None;
        base.TabStop = false;
        base.SetStyle(ControlStyles.Selectable, false);
        base.SetStyle(ControlStyles.UserMouse, true);
        base.SetStyle(ControlStyles.SupportsTransparentBackColor, true);

        base.MouseEnter += delegate(object sender, EventArgs e)
        {
            this.Cursor = Cursors.Default;
        };
    }

    protected override void WndProc(ref Message m)
    {
        if (m.Msg == 0x204) return; // WM_RBUTTONDOWN
        if (m.Msg == 0x205) return; // WM_RBUTTONUP
        base.WndProc(ref m);
    }
}

2) Divisez votre phrase en mots avec l'indicateur IsSelected, qui déterminent si ce mot doit être en gras ou non :

        private void AutocompleteItemControl_Load(object sender, EventArgs e)
    {
        RichTextLabel rtl = new RichTextLabel();
        rtl.Font = new Font("MS Reference Sans Serif", 15.57F);
        StringBuilder sb = new StringBuilder();
        sb.Append(@"{\rtf1\ansi ");
        foreach (var wordPart in wordParts)
        {
            if (wordPart.IsSelected)
            {
                sb.Append(@"\b ");
            }
            sb.Append(ConvertString2RTF(wordPart.WordPart));
            if (wordPart.IsSelected)
            {
                sb.Append(@"\b0 ");
            }
        }
        sb.Append(@"}");

        rtl.Rtf = sb.ToString();
        rtl.Width = this.Width;
        this.Controls.Add(rtl);
    }

3) Ajoutez une fonction pour convertir votre texte en rtf valide (avec support Unicode !) :

   private string ConvertString2RTF(string input)
    {
        //first take care of special RTF chars
        StringBuilder backslashed = new StringBuilder(input);
        backslashed.Replace(@"\", @"\\");
        backslashed.Replace(@"{", @"\{");
        backslashed.Replace(@"}", @"\}");

        //then convert the string char by char
        StringBuilder sb = new StringBuilder();
        foreach (char character in backslashed.ToString())
        {
            if (character <= 0x7f)
                sb.Append(character);
            else
                sb.Append("\\u" + Convert.ToUInt32(character) + "?");
        }
        return sb.ToString();
    }

Sample

Fonctionne à merveille pour moi !Solutions compilées à partir de :

Comment convertir une chaîne en RTF en C# ?

Formater le texte dans la zone de texte enrichi

Comment masquer le curseur dans une RichTextBox ?

  1. Créez le texte sous forme de fichier RTF dans Wordpad
  2. Créer un contrôle de texte enrichi sans bordures et modifiable = false
  3. Ajouter le fichier RTF au projet en tant que ressource
  4. Dans le Form1_load, faites

    monRtfControl.Rtf = Resource1.MyRtfControlText

Étiquette riche automatiquement

      AutoRichLabel with formatted RTF content

Je résolvais ce problème en construisant un UserControl qui contient un TransparentRichTextBox c'est en lecture seule.Le TransparentRichTextBox est un RichTextBox cela permet d'être transparent :

TransparentRichTextBox.cs :

public class TransparentRichTextBox : RichTextBox
{
    [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
    static extern IntPtr LoadLibrary(string lpFileName);

    protected override CreateParams CreateParams
    {
        get
        {
            CreateParams prams = base.CreateParams;
            if (TransparentRichTextBox.LoadLibrary("msftedit.dll") != IntPtr.Zero)
            {
                prams.ExStyle |= 0x020; // transparent 
                prams.ClassName = "RICHEDIT50W";
            }
            return prams;
        }
    }
}

Le final UserControl agit comme un emballage du TransparentRichTextBox.Malheureusement, j'ai dû le limiter à AutoSize à ma manière, parce que le AutoSize de la RichTextBox est devenu cassé.

AutoRichLabel.designer.cs :

partial class AutoRichLabel
{
    /// <summary> 
    /// Required designer variable.
    /// </summary>
    private System.ComponentModel.IContainer components = null;

    /// <summary> 
    /// Clean up any resources being used.
    /// </summary>
    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
    protected override void Dispose(bool disposing)
    {
        if (disposing && (components != null))
        {
            components.Dispose();
        }
        base.Dispose(disposing);
    }

    #region Component Designer generated code

    /// <summary> 
    /// Required method for Designer support - do not modify 
    /// the contents of this method with the code editor.
    /// </summary>
    private void InitializeComponent()
    {
        this.rtb = new TransparentRichTextBox();
        this.SuspendLayout();
        // 
        // rtb
        // 
        this.rtb.BorderStyle = System.Windows.Forms.BorderStyle.None;
        this.rtb.Dock = System.Windows.Forms.DockStyle.Fill;
        this.rtb.Location = new System.Drawing.Point(0, 0);
        this.rtb.Margin = new System.Windows.Forms.Padding(0);
        this.rtb.Name = "rtb";
        this.rtb.ReadOnly = true;
        this.rtb.ScrollBars = System.Windows.Forms.RichTextBoxScrollBars.None;
        this.rtb.Size = new System.Drawing.Size(46, 30);
        this.rtb.TabIndex = 0;
        this.rtb.Text = "";
        this.rtb.WordWrap = false;
        this.rtb.ContentsResized += new System.Windows.Forms.ContentsResizedEventHandler(this.rtb_ContentsResized);
        // 
        // AutoRichLabel
        // 
        this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
        this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
        this.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
        this.BackColor = System.Drawing.Color.Transparent;
        this.Controls.Add(this.rtb);
        this.Name = "AutoRichLabel";
        this.Size = new System.Drawing.Size(46, 30);
        this.ResumeLayout(false);

    }

    #endregion

    private TransparentRichTextBox rtb;
}

AutoRichLabel.cs :

/// <summary>
/// <para>An auto sized label with the ability to display text with formattings by using the Rich Text Format.</para>
/// <para>­</para>
/// <para>Short RTF syntax examples: </para>
/// <para>­</para>
/// <para>Paragraph: </para>
/// <para>{\pard This is a paragraph!\par}</para>
/// <para>­</para>
/// <para>Bold / Italic / Underline: </para>
/// <para>\b bold text\b0</para>
/// <para>\i italic text\i0</para>
/// <para>\ul underline text\ul0</para>
/// <para>­</para>
/// <para>Alternate color using color table: </para>
/// <para>{\colortbl ;\red0\green77\blue187;}{\pard The word \cf1 fish\cf0  is blue.\par</para>
/// <para>­</para>
/// <para>Additional information: </para>
/// <para>Always wrap every text in a paragraph. </para>
/// <para>Different tags can be stacked (i.e. \pard\b\i Bold and Italic\i0\b0\par)</para>
/// <para>The space behind a tag is ignored. So if you need a space behind it, insert two spaces (i.e. \pard The word \bBOLD\0  is bold.\par)</para>
/// <para>Full specification: http://www.biblioscape.com/rtf15_spec.htm </para>
/// </summary>
public partial class AutoRichLabel : UserControl
{
    /// <summary>
    /// The rich text content. 
    /// <para>­</para>
    /// <para>Short RTF syntax examples: </para>
    /// <para>­</para>
    /// <para>Paragraph: </para>
    /// <para>{\pard This is a paragraph!\par}</para>
    /// <para>­</para>
    /// <para>Bold / Italic / Underline: </para>
    /// <para>\b bold text\b0</para>
    /// <para>\i italic text\i0</para>
    /// <para>\ul underline text\ul0</para>
    /// <para>­</para>
    /// <para>Alternate color using color table: </para>
    /// <para>{\colortbl ;\red0\green77\blue187;}{\pard The word \cf1 fish\cf0  is blue.\par</para>
    /// <para>­</para>
    /// <para>Additional information: </para>
    /// <para>Always wrap every text in a paragraph. </para>
    /// <para>Different tags can be stacked (i.e. \pard\b\i Bold and Italic\i0\b0\par)</para>
    /// <para>The space behind a tag is ignored. So if you need a space behind it, insert two spaces (i.e. \pard The word \bBOLD\0  is bold.\par)</para>
    /// <para>Full specification: http://www.biblioscape.com/rtf15_spec.htm </para>
    /// </summary>
    [Browsable(true)]
    public string RtfContent
    {
        get
        {
            return this.rtb.Rtf;
        }
        set
        {
            this.rtb.WordWrap = false; // to prevent any display bugs, word wrap must be off while changing the rich text content. 
            this.rtb.Rtf = value.StartsWith(@"{\rtf1") ? value : @"{\rtf1" + value + "}"; // Setting the rich text content will trigger the ContentsResized event. 
            this.Fit(); // Override width and height. 
            this.rtb.WordWrap = this.WordWrap; // Set the word wrap back. 
        }
    }

    /// <summary>
    /// Dynamic width of the control. 
    /// </summary>
    [Browsable(false)]
    public new int Width
    {
        get
        {
            return base.Width;
        } 
    }

    /// <summary>
    /// Dynamic height of the control. 
    /// </summary>
    [Browsable(false)]
    public new int Height
    {
        get
        {
            return base.Height;
        }
    }

    /// <summary>
    /// The measured width based on the content. 
    /// </summary>
    public int DesiredWidth { get; private set; }

    /// <summary>
    /// The measured height based on the content. 
    /// </summary>
    public int DesiredHeight { get; private set; }

    /// <summary>
    /// Determines the text will be word wrapped. This is true, when the maximum size has been set. 
    /// </summary>
    public bool WordWrap { get; private set; }

    /// <summary>
    /// Constructor. 
    /// </summary>
    public AutoRichLabel()
    {
        InitializeComponent();
    }

    /// <summary>
    /// Overrides the width and height with the measured width and height
    /// </summary>
    public void Fit()
    {
        base.Width = this.DesiredWidth;
        base.Height = this.DesiredHeight;
    }

    /// <summary>
    /// Will be called when the rich text content of the control changes. 
    /// </summary>
    private void rtb_ContentsResized(object sender, ContentsResizedEventArgs e)
    {
        this.AutoSize = false; // Disable auto size, else it will break everything
        this.WordWrap = this.MaximumSize.Width > 0; // Enable word wrap when the maximum width has been set. 
        this.DesiredWidth = this.rtb.WordWrap ? this.MaximumSize.Width : e.NewRectangle.Width; // Measure width. 
        this.DesiredHeight = this.MaximumSize.Height > 0 && this.MaximumSize.Height < e.NewRectangle.Height ? this.MaximumSize.Height : e.NewRectangle.Height; // Measure height. 
        this.Fit(); // Override width and height. 
    }
}

La syntaxe du format texte enrichi est assez simple :

Paragraphe:

{\pard This is a paragraph!\par}

Texte en gras / italique / souligné :

\b bold text\b0
\i italic text\i0
\ul underline text\ul0

Couleur alternative à l'aide de la table des couleurs :

{\colortbl ;\red0\green77\blue187;}
{\pard The word \cf1 fish\cf0  is blue.\par

Mais attention :Enveloppez toujours chaque texte dans un paragraphe.De plus, différentes balises peuvent être empilées (c.-à-d. \pard\b\i Bold and Italic\i0\b0\par) et le caractère espace derrière une balise est ignoré.Donc, si vous avez besoin d'un espace derrière, insérez deux espaces (c'est-à-dire \pard The word \bBOLD\0 is bold.\par).Pour échapper à \ ou { ou }, veuillez utiliser un interligne \.Pour plus d'informations, il existe un spécification complète du format de texte enrichi en ligne.

En utilisant cette syntaxe assez simple, vous pouvez produire quelque chose comme vous pouvez le voir dans la première image.Le contenu en texte enrichi qui était joint au RtfContent propriété de mon AutoRichLabel sur la première image il y avait :

{\colortbl ;\red0\green77\blue187;}
{\pard\b BOLD\b0  \i ITALIC\i0  \ul UNDERLINE\ul0 \\\{\}\par}
{\pard\cf1\b BOLD\b0  \i ITALIC\i0  \ul UNDERLINE\ul0\cf0 \\\{\}\par}

AutoRichLabel with formatted RTF content

Si vous souhaitez activer le retour à la ligne, veuillez définir la largeur maximale à la taille souhaitée.Cependant, cela fixera la largeur à la largeur maximale, même lorsque le texte est plus court.

Amusez-vous!

Il existe un excellent article de 2009 sur Code Project intitulé "Un moteur de rendu HTML professionnel que vous utiliserez" qui implémente quelque chose de similaire à ce que souhaite l'affiche originale.

Je l'utilise avec succès dans plusieurs de nos projets.

Solution très simple :

  1. Ajoutez 2 étiquettes sur le formulaire, LabelA et LabelB
  2. Accédez aux propriétés de LabelA et ancrez-le à gauche.
  3. Accédez aux propriétés de LabelB et ancrez-le également à gauche.
  4. Définissez Font en gras pour LabelA .

Maintenant, le LabelB se décalera en fonction de la longueur du texte de LabelA.

C'est tout.

Je serais également intéressé de savoir si c'est possible.

Lorsque nous n'avons pas trouvé de solution, nous avons eu recours au contrôle 'SuperLabel' de Component Ones qui permet le balisage HTML dans une étiquette.

Sachant qu’il s’agit d’une vieille question, ma réponse s’adresse davantage à ceux, comme moi, qui recherchent encore de telles solutions et tombent sur cette question.

Outre ce qui a déjà été mentionné, DevExpress ContrôleÉtiquette est une étiquette qui prend en charge ce comportement - démo ici.Hélas, cela fait partie d'une bibliothèque payante.

Si vous recherchez des solutions gratuites, je crois Moteur de rendu HTML est la meilleure chose à faire.

Un FlowLayoutPanel fonctionne bien pour votre problème.Si vous ajoutez des étiquettes au panneau de flux et formatez les propriétés de police et de marge de chaque étiquette, vous pouvez alors avoir différents styles de police.Solution assez rapide et facile pour se mettre au travail.

Ouais.Vous pouvez implémenter en utilisant HTML Render.Pour vous voir, cliquez sur le lien : https://htmlrenderer.codeplex.com/J'espère que cela est utile.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top