Wrap Word pour une étiquette dans Windows Forms


184

Comment obtenir la fonctionnalité de retour à la ligne pour un Labeltexte pour qui sort des limites?

Réponses:


167

La réponse rapide: désactivez AutoSize .

Le gros problème ici est que l'étiquette ne changera pas sa hauteur automatiquement (seulement la largeur). Pour ce faire, vous devrez sous-classer l'étiquette et inclure une logique de redimensionnement vertical.

En gros, ce que vous devez faire dans OnPaint est:

  1. Mesurez la hauteur du texte (Graphics.MeasureString).
  2. Si la hauteur de l'étiquette n'est pas égale à la hauteur du texte, définissez la hauteur et le retour.
  3. Dessinez le texte.

Vous devrez également définir l' indicateur de style ResizeRedraw dans le constructeur.


12
Sélectionnez l'étiquette à laquelle vous ajoutez du texte de manière dynamique. Regardez les propriétés de l'étiquette et désactivez AutoSize. Vous serez maintenant en mesure de faire glisser / définir la zone pour l'étiquette et il sera automatiquement enveloppé pour rester dans ces paramètres. Pas besoin de codage supplémentaire.
madeFromCode

C'est précisément ce que je recherchais en ce qui concerne la mise en forme de mon formulaire avec un texte explicatif sous forme de paragraphe.
Philip Brack

1
@madeFromCode Vous auriez besoin de définir la hauteur par programme si vous voulez que l'étiquette se développe verticalement, sinon votre texte sera tronqué.
Edwin

348

En fait, la réponse acceptée est inutilement compliquée.

Si vous définissez l'étiquette sur AutoSize, elle s'agrandira automatiquement avec le texte que vous y mettez. (Cela inclut la croissance verticale.)

Si vous souhaitez que le mot soit renvoyé à une largeur particulière, vous pouvez définir la propriété MaximumSize.

myLabel.MaximumSize = new Size(100, 0);
myLabel.AutoSize = true;

Testé et fonctionne.


10
Si l'étiquette est insérée dans son conteneur, vous pouvez désactiver AutoSize, laisser la propriété max size telle quelle, et elle s'emballe exactement comme nous le voulons. KISS au travail!
TheBlastOne

Vous ne pouvez pas obtenir une largeur fluide avec cette solution.
Robin

1
@Sam: Oui, vous pouvez, il vous suffit de définir les bonnes propriétés "d'ancrage". Avez-vous même essayé?
John Gietzen

1
Sam: vous devriez pouvoir définir la Dockpropriété de l'étiquette et du panneau sur Top, au lieu de ma solution.
John Gietzen

2
Je me suis accroché au OnResizeparent et j'ai appelémyLabel.MaximumSize = new Size(Bounds.Width, 0);
Chris Morgan

23

Dans mon cas (étiquette sur un panneau) j'ai mis label.AutoSize = falseetlabel.Dock = Fill . Et le texte de l'étiquette est automatiquement enveloppé.


Cela fait que l'étiquette remplit tout le formulaire et la rend obscure tous les autres contrôles du formulaire ... Autrement dit, cela ne semble pas fonctionner. Existe-t-il d'autres exigences telles qu'il ne remplira pas tout le formulaire?
Peter Mortensen

5
l'étiquette est sur un panneau , pas directement sur le formulaire. Par conséquent, le texte ne dépasse pas les limites du panneau
alex555

OK, mais cela ne masquerait-il pas toutes les autres commandes du panneau?
Peter Mortensen le

1
Qu'est-ce qui vous empêche de créer un panneau supplémentaire contenant uniquement l'étiquette?
alex555

Cela semble être une mise en page supplémentaire qui devrait être inutile. L'étiquette devrait sûrement avoir sa propre boîte plutôt que de devoir être placée dans une autre boîte.
Edwin

17

Il n'y a pas de propriété autowrap, mais cela peut être fait par programme pour le dimensionner dynamiquement. Voici une solution:

  • Sélectionnez les propriétés de l'étiquette

  • AutoSize = True

  • MaximumSize= ( Largeur , Hauteur ) où Largeur = taille maximale que vous voulez que l'étiquette soit et Hauteur = combien de pixels vous voulez qu'elle enveloppe

    Propriétés de l'échantillon


4
Une dernière remarque, si vous laissez la hauteur maximale à 0, elle continuera à s'étendre verticalement.
palehorse

Mon étiquette ne possède pas les propriétés AutoSize et MaximumSize, comment puis-je les ajouter?
mrbengi

11

À partir de MSDN , enveloppez automatiquement le texte dans l'étiquette :

using System;
using System.Text;
using System.Drawing;
using System.Windows.Forms;

public class GrowLabel : Label {
    private bool mGrowing;
    public GrowLabel() {
        this.AutoSize = false;
    }
    private void resizeLabel() {
        if (mGrowing) 
            return;
        try {
            mGrowing = true;
            Size sz = new Size(this.Width, Int32.MaxValue);
            sz = TextRenderer.MeasureText(this.Text, this.Font, sz, TextFormatFlags.WordBreak);
            this.Height = sz.Height;
        }
        finally {
            mGrowing = false;
        }
    }
    protected override void OnTextChanged(EventArgs e) {
        base.OnTextChanged(e);
        resizeLabel();
    }
    protected override void OnFontChanged(EventArgs e) {
        base.OnFontChanged(e);
        resizeLabel();
    }
    protected override void OnSizeChanged(EventArgs e) {
        base.OnSizeChanged(e);
        resizeLabel();
    }
}

Afin de couper sur des caractères plutôt que des mots (utile lorsque vous avez de longues chaînes sans espaces tels que les chemins de fichiers), utilisez plutôt (TextFormatFlags.WordBreak | TextFormatFlags.TextBoxControl). Voir le dernier message dans le même fil MSDN.
Ohad Schneider

1
N'oubliez pas non plus d'inclure le remplissage supérieur et inférieur de l'étiquette dans le calcul ( Height = sz.Height + Padding.Vertical;)
Igor Brejc

6

Je devais trouver une solution rapide, alors j'ai juste utilisé un TextBox avec ces propriétés:

var myLabel = new TextBox
                    {
                        Text = "xxx xxx xxx",
                        WordWrap = true,
                        AutoSize = false,
                        Enabled = false,
                        Size = new Size(60, 30),
                        BorderStyle = BorderStyle.None,
                        Multiline =  true,
                        BackColor =  container.BackColor
                    };

C'est une bonne solution, mais je préférerais peut-être utiliser ReadOnly à la définition de Enabled sur false.
PahJoker

1
Il s'agit d'une solution imaginative qui fonctionne également bien sur Compact Framework (où Label n'a pas les propriétés AutoSize et MaximumSize).
Tim Coulter

3

Ayez un meilleur basé sur la réponse de @hypo

public class GrowLabel : Label {
    private bool mGrowing;
    public GrowLabel() {
        this.AutoSize = false;
    }
    private void resizeLabel() {
        if (mGrowing)
            return;
        try {
            mGrowing = true;
            int width = this.Parent == null ? this.Width : this.Parent.Width;

            Size sz = new Size(this.Width, Int32.MaxValue);
            sz = TextRenderer.MeasureText(this.Text, this.Font, sz, TextFormatFlags.WordBreak);
            this.Height = sz.Height + Padding.Bottom + Padding.Top;
        } finally {
            mGrowing = false;
        }
    }
    protected override void OnTextChanged(EventArgs e) {
        base.OnTextChanged(e);
        resizeLabel();
    }
    protected override void OnFontChanged(EventArgs e) {
        base.OnFontChanged(e);
        resizeLabel();
    }
    protected override void OnSizeChanged(EventArgs e) {
        base.OnSizeChanged(e);
        resizeLabel();
    }
}

int width = this.Parent == null ? this.Width : this.Parent.Width; cela vous permet d'utiliser l'étiquette de croissance automatique lorsqu'elle est ancrée à un parent, par exemple un panneau.

this.Height = sz.Height + Padding.Bottom + Padding.Top; ici nous nous occupons du rembourrage pour le haut et le bas.


1
  1. Mettez l'étiquette dans un panneau
  2. Manipulez le ClientSizeChanged eventpour le panneau, en faisant que l'étiquette remplisse l'espace:

    private void Panel2_ClientSizeChanged(object sender, EventArgs e)
    {
        label1.MaximumSize = new Size((sender as Control).ClientSize.Width - label1.Left, 10000);
    }
  3. Définir Auto-Sizepour l'étiquette surtrue

  4. Définir Dockpour l'étiquette surFill

Les étapes 3 et 4 sont-elles effectuées dans le concepteur? Une raison pour laquelle ils sont aux étapes 3 et 4?
Stealth Rabbi

Ils sont effectués dans le concepteur (mais peuvent être effectués dans le code si vous en avez besoin) et il n'y a aucune raison pour la commande.
noelicus

1

Je ne suis pas sûr que cela conviendra à tous les cas d'utilisation, mais j'utilise souvent une astuce simple pour obtenir le comportement d'emballage: mettez votre Labelavec à l' AutoSize=falseintérieur d'un 1x1 TableLayoutPanelqui prendra soin de la Labeltaille du.


1

Définissez la propriété AutoEllipsis sur «TRUE» et la propriété AutoSize sur «FALSE».

entrez la description de l'image ici

entrez la description de l'image ici


0

Si votre panneau limite la largeur de votre étiquette, vous pouvez définir la propriété Anchor de votre étiquette sur Left, Right et définir AutoSize sur true. Ceci est conceptuellement similaire à l'écoute de l' SizeChangedévénement du Panel et à la mise à jour de MaximumSize de l'étiquette en a new Size(((Control)sender).Size.Width, 0)comme suggéré par une réponse précédente . Chaque côté répertorié dans la propriété Anchor est, bien, ancré au côté interne respectif du contrôle conteneur. Ainsi, la liste de deux côtés opposés dans Anchor définit effectivement la dimension du contrôle. L'ancrage à gauche et à droite définit la propriété Width du contrôle et l'ancrage en haut et en bas définit sa propriété Height.

Cette solution, comme C #:

label.Anchor = AnchorStyles.Left | AnchorStyles.Right;
label.AutoSize = true;

Ça ne marche pas. L'étiquette augmente la largeur de mon panneau juste qu'il n'a pas à s'enrouler. Malheureusement, la fenêtre n'est pas aussi large.
ygoe

0

Si vous voulez vraiment définir la largeur de l'étiquette indépendamment du contenu, je trouve que le moyen le plus simple est le suivant:

  • Définir la taille automatique sur true
  • Définissez la largeur maximale comme vous le souhaitez
  • Définir la largeur minimale de manière identique

Maintenant, l'étiquette est de largeur constante, mais elle adapte sa hauteur automatiquement.

Ensuite, pour le texte dynamique, diminuez la taille de la police. Si nécessaire, utilisez cet extrait de code dans le sous où le texte de l'étiquette est défini:

If Me.Size.Height - (Label12.Location.Y + Label12.Height) < 20 Then
    Dim naam As String = Label12.Font.Name
    Dim size As Single = Label12.Font.SizeInPoints - 1
    Label12.Font = New Font(naam, size)
End If

0

Cela m'a aidé dans mon formulaire appelé InpitWindow: In Designer for Label:

AutoSize = true;
Achors = Top, Left, Right.

private void InputWindow_Shown(object sender, EventArgs e) {
    lbCaption.MaximumSize = new Size(this.ClientSize.Width - btOK.Width - btOK.Margin.Left - btOK.Margin.Right -
        lbCaption.Margin.Right - lbCaption.Margin.Left, 
        Screen.GetWorkingArea(this).Height / 2);
    this.Height = this.Height + (lbCaption.Height - btOK.Height - btCancel.Height);
    //Uncomment this line to prevent form height chage to values lower than initial height
    //this.MinimumSize = new Size(this.MinimumSize.Width, this.Height);
}
//Use this handler if you want your label change it size according to form clientsize.
private void InputWindow_ClientSizeChanged(object sender, EventArgs e) {
    lbCaption.MaximumSize = new Size(this.ClientSize.Width - btOK.Width - btOK.Margin.Left * 2 - btOK.Margin.Right * 2 -
        lbCaption.Margin.Right * 2 - lbCaption.Margin.Left * 2,
        Screen.GetWorkingArea(this).Height / 2);
}

Code entier de mon formulaire


0

Si les dimensions du bouton doivent rester inchangées:

myButton.Text = "word\r\nwrapped"

0

La réponse simple à ce problème consiste à modifier la propriété DOCK de l'étiquette. Il est "AUCUN" par défaut.


0

Si vous saisissez au préalable du texte dans l'étiquette, vous pouvez le faire.

  1. Dans le concepteur, faites un clic droit sur l'étiquette et cliquez sur Propriétés.
  2. Dans Propriétés, recherchez l'onglet de texte.
  3. Cliquez dans l'onglet et cliquez sur le bouton fléché à côté.
  4. Une boîte apparaîtra dessus.
  5. Vous pouvez appuyer sur Entrée dans la boîte contextuelle pour ajouter des lignes et taper comme dans le bloc-notes! (APPUYEZ SUR ENTRER O VOUS VOULEZ ENVELOPPER LE TEXTE DE L'ÉTIQUETTE)

-12

Utilisez style="overflow:Scroll"dans l'étiquette comme dans le HTML ci-dessous. Cela ajoutera la barre de défilement dans l'étiquette dans le panneau.

<asp:Label
    ID="txtAOI"
    runat="server"
    style="overflow:Scroll"
    CssClass="areatext"
    BackColor="White"
    BorderColor="Gray"
    BorderWidth="1"
    Width = "900" ></asp:Label>

3
C'est bien de voter, mais dites au moins pourquoi vous l'avez fait. La raison pour laquelle cela a été rejeté est parce qu'un <asp: Label> n'est pas utilisé dans WinForms. Cette réponse est pour la mauvaise plateforme.
theJerm

4
parce que c'est asp.net pas winform
Trikaldarshi
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.