A capo automatico per un'etichetta in Windows Form


184

Come si può ottenere la funzionalità di Labelritorno a capo automatico per un testo for che va oltre i limiti?

Risposte:


167

La risposta rapida: disattiva AutoSize .

Il grande problema qui è che l'etichetta non cambierà automaticamente la sua altezza (solo larghezza). Per farlo bene dovrai sottoclassare l'etichetta e includere la logica di ridimensionamento verticale.

Fondamentalmente quello che devi fare in OnPaint è:

  1. Misura l'altezza del testo (Graphics.MeasureString).
  2. Se l'altezza dell'etichetta non è uguale all'altezza del testo, impostare l'altezza e il ritorno.
  3. Disegna il testo.

Dovrai anche impostare il flag di stile ResizeRedraw nel costruttore.


12
Seleziona l'etichetta a cui stai aggiungendo dinamicamente il testo. Guarda le proprietà dell'etichetta e disattiva AutoSize. Ora sarai in grado di trascinare / impostare l'area per l'etichetta e si avvolgerà automaticamente per rimanere all'interno di quei parametri. Non è necessaria alcuna codifica aggiuntiva.
madeFromCode

Questo è esattamente quello che stavo cercando in quanto riguarda la formattazione del mio modulo con testo esplicativo che si trova in un modulo di paragrafo.
Philip Brack,

1
@madeFromCode Dovresti impostare l'altezza a livello di codice se desideri che l'etichetta si espanda verticalmente, altrimenti il ​​testo verrà troncato.
Edwin,

348

In realtà, la risposta accettata è inutilmente complicata.

Se imposti l'etichetta su AutoSize, questa si espanderà automaticamente con qualsiasi testo inserito. (Ciò include la crescita verticale.)

Se si desidera renderlo a capo automatico con una larghezza particolare, è possibile impostare la proprietà MaximumSize.

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

Testato e funziona.


10
Se l'etichetta è inserita nel relativo contenitore, è possibile disattivare AutoSize, lasciare la proprietà di dimensione massima così com'è e verrà racchiusa la parola esattamente come desideriamo. BACIO al lavoro!
TheBlastOne

Non è possibile ottenere una larghezza del fluido con quella soluzione.
Robin,

1
@Sam: Sì, puoi semplicemente impostare le proprietà "anchor" appropriate. L'hai mai provato?
John Gietzen,

1
Sam: dovresti essere in grado di impostare la Dockproprietà sia dell'etichetta che del pannello Top, invece della mia soluzione.
John Gietzen,

2
Ho bloccato a OnResizenel genitore e callmyLabel.MaximumSize = new Size(Bounds.Width, 0);
Chris Morgan

23

Nel mio caso (etichetta su un pannello) ho impostato label.AutoSize = falsee label.Dock = Fill. E il testo dell'etichetta viene spostato automaticamente.


Questo rende l'etichetta riempire l'intero modulo e renderlo oscuro tutti gli altri controlli nel modulo ... Cioè, sembra non funzionare. Esistono altri requisiti tali da non riempire l'intero modulo?
Peter Mortensen,

5
l'etichetta si trova su un pannello , non direttamente sul modulo. Pertanto il testo non supera i limiti del pannello
alex555

OK, ma allora non oscurerebbe tutti gli altri controlli nel pannello?
Peter Mortensen,

1
Cosa ti impedisce di creare un pannello aggiuntivo contenente solo l'etichetta?
alex555,

Sembra un layout extra che non dovrebbe essere necessario. Sicuramente l'etichetta dovrebbe avere una sua scatola piuttosto che dover essere inserita in un'altra scatola.
Edwin,

17

Non esiste una proprietà autowrap ma questo può essere fatto a livello di codice per ridimensionarlo in modo dinamico. Ecco una soluzione:

  • Seleziona le proprietà dell'etichetta

  • AutoSize = True

  • MaximumSize= ( Larghezza , Altezza ) dove Larghezza = dimensione massima desiderata per l'etichetta e Altezza = quanti pixel si desidera avvolgere

    Proprietà campione


4
Un'altra nota, se si lascia l'altezza massima a 0, continuerà ad espandersi verticalmente.
cavallo pallido

La mia etichetta non ha le proprietà AutoSize e MaximumSize, come posso aggiungerle?
mrbengi,

11

Da MSDN , avvolgi automaticamente il testo nell'etichetta :

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

Per interrompere i caratteri anziché le parole (utile quando si hanno stringhe lunghe senza spazi come i percorsi dei file), utilizzare invece (TextFormatFlags.WordBreak | TextFormatFlags.TextBoxControl). Vedi l'ultimo post nella stessa discussione MSDN.
Ohad Schneider,

1
Inoltre, non dimenticare di includere l'imbottitura superiore e inferiore dell'etichetta nel calcolo ( Height = sz.Height + Padding.Vertical;)
Igor Brejc,

6

Ho dovuto trovare una soluzione rapida, quindi ho appena usato un TextBox con quelle proprietà:

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

Questa è una buona soluzione, ma potrei preferire usare ReadOnly per impostare Enabled su false.
PahJoker

1
Questa è una soluzione fantasiosa che funziona bene anche su Compact Framework (dove Label non ha proprietà AutoSize e MaximumSize).
Tim Coulter,

3

Avere uno migliore basato sulla risposta di @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; ciò consente di utilizzare un'etichetta di crescita automatica quando è ancorata a un genitore, ad esempio un pannello.

this.Height = sz.Height + Padding.Bottom + Padding.Top; qui ci occupiamo dell'imbottitura per la parte superiore e inferiore.


1
  1. Metti l'etichetta all'interno di un pannello
  2. Gestisci ClientSizeChanged eventper il pannello, facendo in modo che l'etichetta riempia lo spazio:

    private void Panel2_ClientSizeChanged(object sender, EventArgs e)
    {
        label1.MaximumSize = new Size((sender as Control).ClientSize.Width - label1.Left, 10000);
    }
  3. Impostare Auto-Sizeper l'etichetta sutrue

  4. Impostare Dockper l'etichetta suFill

I passaggi 3 e 4 sono stati eseguiti nel designer? Qualche motivo per cui sono i passaggi 3 e 4?
Rabbino

Sono fatti nel designer (ma potrebbero essere fatti nel codice se ne hai bisogno) e non c'è motivo per l'ordine.
Noelico

1

Non sono sicuro che andrà bene tutti i casi d'uso, ma spesso mi utilizzare un semplice trucco per ottenere il comportamento di avvolgimento: mettere il vostro Labelcon AutoSize=falseall'interno di un 1x1 TableLayoutPanel, che si prenderà cura del Label's dimensioni.


1

Impostare la proprietà AutoEllipsis su "TRUE" e la proprietà AutoSize su "FALSE".

inserisci qui la descrizione dell'immagine

inserisci qui la descrizione dell'immagine


0

Se il pannello limita la larghezza dell'etichetta, è possibile impostare la proprietà Anchor dell'etichetta su Sinistra, Destra e AutoSize su true. Ciò è concettualmente simile all'ascolto SizeChangeddell'evento del Pannello e all'aggiornamento del MaximumSize dell'etichetta a new Size(((Control)sender).Size.Width, 0)come suggerito da una risposta precedente . Ogni lato elencato nella proprietà Anchor è, bene, ancorato al rispettivo lato interno del Controllo contenente. Quindi elencare due lati opposti in Anchor imposta in modo efficace la dimensione del controllo. Ancoraggio a sinistra e a destra imposta la proprietà Larghezza del controllo e Ancoraggio su in alto e in basso imposta la proprietà Altezza.

Questa soluzione, come C #:

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

Non funziona L'etichetta aumenta la larghezza del mio pannello solo che non deve avvolgere. Sfortunatamente, la finestra non è così ampia.
giovedì

0

Se vuoi davvero impostare la larghezza dell'etichetta indipendentemente dal contenuto, trovo che il modo più semplice sia questo:

  • Imposta il ridimensionamento automatico vero
  • Imposta la larghezza massima nel modo desiderato
  • Impostare la larghezza minima in modo identico

Ora l'etichetta ha una larghezza costante, ma adatta automaticamente la sua altezza.

Quindi, per il testo dinamico, ridurre la dimensione del carattere. Se necessario, utilizza questo snippet nel sottotitolo in cui è impostato il testo dell'etichetta:

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

Questo mi ha aiutato nel mio modulo chiamato 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);
}

Codice intero del mio modulo


0

Se le dimensioni del pulsante devono essere mantenute invariate:

myButton.Text = "word\r\nwrapped"

0

La semplice risposta a questo problema è modificare la proprietà DOCK dell'etichetta. È "NONE" per impostazione predefinita.


0

Se si inserisce prima del testo nell'etichetta, è possibile farlo.

  1. Nel designer, fare clic con il tasto destro sull'etichetta e fare clic su Proprietà.
  2. In Proprietà, cerca la scheda di testo.
  3. Fai clic sulla scheda e fai clic sul pulsante freccia accanto ad essa.
  4. Una finestra si aprirà sopra di essa.
  5. È possibile premere Invio nella casella popup per aggiungere righe e digitare come nel blocco note! (PREMERE INVIO DOVE VUOI SCRIVERE IL TESTO DELL'ETICHETTA)

-12

Utilizzare style="overflow:Scroll"nell'etichetta come nel codice HTML di seguito. Ciò aggiungerà la barra di scorrimento nell'etichetta all'interno del pannello.

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

3
Votare questo va bene, ma almeno dire perché l'hai fatto. Il motivo per cui questo è stato votato è perché un <asp: Label> non è usato in WinForms. Questa risposta è per la piattaforma sbagliata.
theJerm

4
perché non è asp.net winform
Trikaldarshi
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.