A capo automatico per un'etichetta in Windows Form
Domanda
Come possiamo ottenere la funzionalità di ritorno a capo automatico per un'etichetta in Windows Form ?
Ho inserito un'etichetta in un pannello e ho aggiunto del testo all'etichetta in modo dinamico. Ma supera la lunghezza del pannello. Come posso risolvere questo?
Soluzione
La risposta rapida: disattiva off Dimensione automatica .
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 è:
- Misura l'altezza del testo (Graphics.MeasureString).
- Se l'altezza dell'etichetta non è uguale all'altezza del testo, impostare l'altezza e il ritorno.
- Disegna il testo.
Dovrai anche impostare ResizeRedraw flag di stile nel costruttore.
Altri suggerimenti
In realtà, la risposta accettata è inutilmente complicata.
Se imposti l'etichetta su AutoSize, si espanderà automaticamente con qualsiasi testo inserito. (Ciò include la crescita verticale.)
Se vuoi renderlo a capo automatico con una larghezza particolare, puoi impostare la proprietà MaximumSize.
myLabel.MaximumSize = new Size(100, 0);
myLabel.AutoSize = true;
Testato e funzionante.
Nel mio caso (etichetta su un pannello) ho impostato label.AutoSize = false
e label.Dock = Fill
.
E il testo dell'etichetta viene spostato automaticamente.
Cattive notizie: non esiste una proprietà autowrap.
Buone notizie: c'è una luce alla fine del tunnel!
Puoi farlo a livello di codice per ridimensionarlo in modo dinamico, ma ecco la soluzione più semplice:
- Seleziona le proprietà dell'etichetta
- AutoSize = True
-
MaximumSize = ( Larghezza , Altezza ) dove Larghezza = dimensione massima desiderata per l'etichetta e Altezza = quanti pixel vuoi che siano racchiusi
Da MSDN , Avvolgi automaticamente il testo in 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();
}
}
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
};
Ne hai 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;
ti consente di utilizzare l'etichetta di crescita automatica quando ancorato a un genitore, ad es. un pannello.
this.Height = sz.Height + Padding.Bottom + Padding.Top;
qui ci occupiamo dell'imbottitura per la parte superiore e inferiore.
- Metti l'etichetta all'interno di un pannello
-
Gestisci
l'evento ClientSizeChanged
per il pannello, creando il etichetta riempire lo spazio:private void Panel2_ClientSizeChanged(object sender, EventArgs e) { label1.MaximumSize = new Size((sender as Control).ClientSize.Width - label1.Left, 10000); }
-
Imposta
Dimensione automatica
per l'etichetta sutrue
- Impostare
Dock
per l'etichetta suFill
Non sono sicuro che si adatta a tutti i casi d'uso, ma spesso uso un semplice trucco per ottenere il comportamento di avvolgimento:
inserisci il tuo Label
con AutoSize = false
all'interno di un <1> TableLayoutPanel
che si occuperà della dimensione del Label
.
Se il pannello sta limitando la larghezza dell'etichetta, puoi impostare la proprietà Anchor dell'etichetta su Sinistra, Destra e AutoSize su true. Ciò è concettualmente simile all'ascolto dell'evento SizeChanged
del Pannello e all'aggiornamento dell'etichetta MaximumSize a un new Size (((Control) mittente) .Size.Width, 0)
come suggerito da una risposta precedente . Ogni lato elencato nella proprietà Anchor è, bene, ancorato al rispettivo lato interno del Control. 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 imposterà la proprietà Altezza.
Questa soluzione, come C #:
label.Anchor = AnchorStyles.Left | AnchorStyles.Right;
label.AutoSize = true;
Se vuoi davvero impostare la larghezza dell'etichetta indipendentemente dal contenuto, trovo che il modo più semplice sia questo:
- Imposta autosize true
- Imposta la larghezza massima nel modo desiderato
- Imposta identicamente la larghezza minima
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 frammento 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
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);
}
Se le dimensioni del pulsante devono essere mantenute invariate:
myButton.Text = "word\r\nwrapped"
La semplice risposta a questo problema è cambiare la proprietà DOCK dell'etichetta. È "NESSUNO" per impostazione predefinita.
Usa style = " overflow: scorri "
nell'etichetta come nel codice HTML sottostante. 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>