Word wrap para una etiqueta en Windows Forms

Respuestas:

167

La respuesta rápida: apague AutoSize .

El gran problema aquí es que la etiqueta no cambiará su altura automáticamente (solo ancho). Para hacerlo correctamente, deberá subclasificar la etiqueta e incluir la lógica de cambio de tamaño vertical.

Básicamente, lo que debe hacer en OnPaint es:

  1. Mida la altura del texto (Graphics.MeasureString).
  2. Si la altura de la etiqueta no es igual a la altura del texto, configure la altura y regrese.
  3. Dibuja el texto.

También deberá establecer el indicador de estilo ResizeRedraw en el constructor.

Jonathan C Dickinson
fuente
12
Seleccione la etiqueta a la que está agregando texto dinámicamente. Mire las propiedades de la etiqueta y desactive Tamaño automático. Ahora podrá arrastrar / establecer el área para la etiqueta y se ajustará automáticamente para permanecer dentro de esos parámetros. No hay necesidad de ninguna codificación adicional.
madeFromCode
Esto es precisamente lo que estaba buscando, ya que se refiere al formato de mi formulario con texto explicativo que está en forma de párrafo.
Philip Brack el
1
@madeFromCode Debería establecer la altura mediante programación si desea que la etiqueta se expanda verticalmente; de ​​lo contrario, su texto se recortará.
Edwin
348

En realidad, la respuesta aceptada es innecesariamente complicada.

Si configura la etiqueta en AutoSize, crecerá automáticamente con el texto que ponga. (Esto incluye crecimiento vertical).

Si desea que se ajuste la palabra en un ancho particular, puede establecer la propiedad MaximumSize.

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

Probado y funciona.

John Gietzen
fuente
10
Si tiene la etiqueta encajada en su contenedor, puede desactivar AutoSize, dejar la propiedad de tamaño máximo como está y se ajustará exactamente como queramos. BESO en el trabajo!
TheBlastOne
No puede lograr un ancho de fluido con esa solución.
Robin
1
@Sam: Sí, puedes establecer las propiedades de "ancla" adecuadas. ¿Lo has probado?
John Gietzen
1
Sam: deberías poder establecer la Dockpropiedad de la etiqueta y el panel en Toplugar de mi solución.
John Gietzen
2
Me he aferrado a OnResizela matriz y la llamadamyLabel.MaximumSize = new Size(Bounds.Width, 0);
Chris Morgan
23

En mi caso (etiqueta en un panel) configuré label.AutoSize = falsey label.Dock = Fill. Y el texto de la etiqueta se ajusta automáticamente.

alex555
fuente
Esto hace que la etiqueta llene todo el formulario y oscurezca todos los demás controles en el formulario ... Es decir, no parece funcionar. ¿Existen otros requisitos para que no complete todo el formulario?
Peter Mortensen
55
la etiqueta está en un panel , no en el formulario directamente. Por lo tanto, el texto no excede los límites del panel
alex555
Está bien, pero ¿no oscurecería todos los demás controles en el panel?
Peter Mortensen
1
¿Qué le impide crear un panel adicional que contenga solo la etiqueta?
alex555
Eso parece un diseño extra que debería ser innecesario. Seguramente la etiqueta debe tener su propia caja en lugar de tener que ponerla en otra caja.
Edwin
17

No existe una propiedad de ajuste automático, pero esto se puede hacer mediante programación para dimensionarlo dinámicamente. Aquí hay una solución:

  • Seleccione las propiedades de la etiqueta.

  • AutoSize = True

  • MaximumSize= ( Ancho , Altura ) donde Ancho = tamaño máximo que desea que sea la etiqueta y Altura = cuántos píxeles desea que se ajuste

    Propiedades de muestra

Sebastian Castaldi
fuente
44
Una nota más, si deja la altura máxima en 0, continuará expandiéndose verticalmente.
palehorse
Mi etiqueta no tiene las propiedades AutoSize y MaximumSize, ¿cómo puedo agregarlas?
mrbengi
11

Desde MSDN , Ajustar automáticamente el texto en la etiqueta :

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();
    }
}
hipo
fuente
Para dividir los caracteres en lugar de las palabras (útil cuando tiene cadenas largas sin espacios como rutas de archivos), use (TextFormatFlags.WordBreak | TextFormatFlags.TextBoxControl). Vea la última publicación en el mismo hilo de MSDN.
Ohad Schneider
1
Además, no olvide incluir el relleno superior e inferior de la etiqueta en el cálculo ( Height = sz.Height + Padding.Vertical;)
Igor Brejc
6

Tenía que encontrar una solución rápida, así que solo usé un TextBox con esas propiedades:

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
                    };
usuario3356581
fuente
Esta es una buena solución, pero podría preferir usar ReadOnly a establecer Enabled en false.
PahJoker
1
Esta es una solución imaginativa que también funciona bien en Compact Framework (donde Label no tiene las propiedades AutoSize y MaximumSize).
Tim Coulter
3

Tener uno mejor basado en la respuesta 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; esto le permite usar la etiqueta de crecimiento automático cuando está acoplada a un padre, por ejemplo, un panel.

this.Height = sz.Height + Padding.Bottom + Padding.Top; aquí nos encargamos del relleno para arriba y abajo.

marzo1993
fuente
1
  1. Ponga la etiqueta dentro de un panel
  2. Maneje el ClientSizeChanged eventpara el panel, haciendo que la etiqueta llene el espacio:

    private void Panel2_ClientSizeChanged(object sender, EventArgs e)
    {
        label1.MaximumSize = new Size((sender as Control).ClientSize.Width - label1.Left, 10000);
    }
  3. Establecer Auto-Sizepara la etiqueta atrue

  4. Establecer Dockpara la etiqueta aFill
noelicus
fuente
¿Se realizan los pasos 3 y 4 en el diseñador? ¿Alguna razón por la cual son los pasos 3 y 4?
Stealth Rabbi
Se realizan en el diseñador (pero se pueden hacer en código si lo necesita) y no hay razón para el pedido.
noelicus
1

No estoy seguro de que encajará todos los casos de uso, pero a menudo utilizar un simple truco para obtener el comportamiento de embalaje: poner su Labelcon AutoSize=falseel interior de un 1x1 TableLayoutPanelque se encargará del Labeltamaño 's.

Pragmateek
fuente
1

Establezca la propiedad AutoEllipsis en 'TRUE' y la propiedad AutoSize en 'FALSE'.

ingrese la descripción de la imagen aquí

ingrese la descripción de la imagen aquí

Ravi Kumar GN
fuente
0

Si su panel está limitando el ancho de su etiqueta, puede establecer la propiedad Anchor de su etiqueta en Left, Right y establecer AutoSize en true. Esto es conceptualmente similar a escuchar el SizeChangedevento del Panel y actualizar el Tamaño máximo de la etiqueta a new Size(((Control)sender).Size.Width, 0)lo sugerido por una respuesta anterior . Todos los lados enumerados en la propiedad Anchor están, bueno, anclados al lado interno respectivo del Control que lo contiene. Entonces, enumerar dos lados opuestos en Anchor establece efectivamente la dimensión del control. Anclar a izquierda y derecha establece la propiedad Ancho del control y Anclar a superior e inferior establecería su propiedad Altura.

Esta solución, como C #:

label.Anchor = AnchorStyles.Left | AnchorStyles.Right;
label.AutoSize = true;
binki
fuente
No funciona La etiqueta aumenta el ancho de mi panel solo para que no tenga que ajustarse. Lamentablemente, la ventana no es tan amplia.
Ygoe
0

Si realmente desea establecer el ancho de la etiqueta independientemente del contenido, creo que la forma más fácil es esta:

  • Establecer tamaño automático verdadero
  • Establezca el ancho máximo como lo desee
  • Establecer el ancho mínimo de forma idéntica

Ahora la etiqueta tiene un ancho constante, pero adapta su altura automáticamente.

Luego, para el texto dinámico, disminuya el tamaño de la fuente. Si es necesario, use este fragmento en el subtítulo donde se establece el texto de la etiqueta:

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
Kjell Verbeke
fuente
0

Esto me ayudó en mi formulario llamado 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);
}

Código completo de mi formulario

Micrófono
fuente
0

Si las dimensiones del botón deben mantenerse sin cambios:

myButton.Text = "word\r\nwrapped"
rjain
fuente
0

La respuesta simple para este problema es cambiar la propiedad DOCK de la etiqueta. Es "NINGUNO" por defecto.

Sunil Neeradi
fuente
0

Si está ingresando texto en la etiqueta de antemano, puede hacerlo.

  1. En el diseñador, haga clic derecho en la etiqueta y haga clic en Propiedades.
  2. En Propiedades, busque la pestaña de texto.
  3. Haga clic en la pestaña y haga clic en el botón de flecha al lado.
  4. Aparecerá una caja encima de ella.
  5. ¡Puede presionar enter en el cuadro emergente para agregar líneas y escribir como en el bloc de notas! (PRESIONE ENTRAR DONDE QUIERE ENVOLVER EL TEXTO DE LA ETIQUETA)
DJ
fuente
-12

Úselo style="overflow:Scroll"en la etiqueta como en el siguiente HTML. Esto agregará la barra de desplazamiento en la etiqueta dentro del panel.

<asp:Label
    ID="txtAOI"
    runat="server"
    style="overflow:Scroll"
    CssClass="areatext"
    BackColor="White"
    BorderColor="Gray"
    BorderWidth="1"
    Width = "900" ></asp:Label>
Cariño jain
fuente
3
Votar esto está bien, pero al menos diga por qué lo hizo. La razón por la que se rechazó esto es porque no se usa <asp: Label> en WinForms. Esta respuesta es para la plataforma incorrecta.
theJerm
44
porque es asp.net no winform
Trikaldarshi