Quebra de linha para um rótulo no Windows Forms


184

Como se pode obter a funcionalidade de quebra de linha para um Labeltexto fora dos limites?

Respostas:


167

A resposta rápida: desligue o AutoSize .

O grande problema aqui é que o rótulo não altera sua altura automaticamente (somente largura). Para fazer isso direito, você precisará subclassificar o rótulo e incluir lógica de redimensionamento vertical.

Basicamente, o que você precisa fazer no OnPaint é:

  1. Meça a altura do texto (Graphics.MeasureString).
  2. Se a altura da etiqueta não for igual à altura do texto, defina a altura e retorne.
  3. Desenhe o texto.

Você também precisará definir o sinalizador de estilo ResizeRedraw no construtor.


12
Selecione o rótulo ao qual você está adicionando texto dinamicamente. Observe as propriedades do rótulo e desative o AutoSize. Agora você poderá arrastar / definir a área da etiqueta e ela será automaticamente quebrada automaticamente para permanecer dentro desses parâmetros. Não há necessidade de codificação adicional.
— madeFromCode

Isto é precisamente o que eu estava procurando, no que se refere à formatação do meu formulário com texto explicativo que está no formato de parágrafo.
— Philip Brack

1
@madeFromCode Você precisaria definir a altura programaticamente se quiser que o rótulo se expanda verticalmente, caso contrário o texto será cortado.
— Edwin

348

Na verdade, a resposta aceita é desnecessariamente complicada.

Se você definir o rótulo para AutoSize, ele aumentará automaticamente com o texto que você inserir nele. (Isso inclui crescimento vertical.)

Se você deseja torná-lo com quebra de linha em uma largura específica, pode definir a propriedade MaximumSize.

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

Testado e funciona.


10
Se o rótulo estiver encaixado no contêiner, você poderá desativar o AutoSize, deixar a propriedade de tamanho máximo como está e será quebrada exatamente como queremos. BEIJO no trabalho!
— TheBlastOne

Você não pode obter uma largura de fluido com essa solução.
— Robin

1
@ Sam: Sim, você pode, basta definir as propriedades "âncora" adequadas. Você já tentou isso?
— John Gietzen

1
Sam: você deve poder definir a Dockpropriedade do rótulo e do painel para Top, em vez da minha solução.
— John Gietzen

2
Eu entrei OnResizeno pai e ligueimyLabel.MaximumSize = new Size(Bounds.Width, 0);
— Chris Morgan

23

No meu caso (etiqueta em um painel), defino label.AutoSize = falsee label.Dock = Fill. E o texto do rótulo é quebrado automaticamente.


Isso faz com que o rótulo preencha todo o formulário e obscurece todos os outros controles no formulário ... Ou seja, parece não funcionar. Existem outros requisitos que não preenchem o formulário inteiro?
— Peter Mortensen

5
o rótulo está em um painel , não no formulário diretamente. Portanto, o texto não excede os limites do painel
— alex555 14/01

OK, mas não ocultaria todos os outros controles no painel?
— Peter Mortensen

1
O que impede você de criar um painel extra contendo apenas o rótulo?
— precisa saber é

Parece um layout extra que deve ser desnecessário. Certamente, o rótulo deve ter sua própria caixa, em vez de precisar ser colocado em outra caixa.
— Edwin

17

Não há propriedade de quebra automática, mas isso pode ser feito programaticamente para dimensioná-lo dinamicamente. Aqui está uma solução:

  • Selecione as propriedades do rótulo

  • AutoSize = True

  • MaximumSize= ( Largura , Altura ), em que Largura = tamanho máximo que você deseja que o rótulo seja e Altura = quantos pixels você deseja que ele envolva

    Propriedades da amostra


4
Mais uma nota, se você deixar a altura máxima em 0, ela continuará a se expandir verticalmente.
— Palehorse

Meu rótulo não possui as propriedades AutoSize e MaximumSize, como posso adicioná-las?
— precisa saber é o seguinte

11

No MSDN , agrupar automaticamente o texto no rótulo :

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

Para quebrar caracteres em vez de palavras (útil quando você tem longas seqüências sem espaços, como caminhos de arquivo), use (TextFormatFlags.WordBreak | TextFormatFlags.TextBoxControl). Veja a última postagem no mesmo thread do MSDN.
— Oade Schneider

1
Além disso, não se esqueça de incluir o preenchimento superior e inferior do rótulo no cálculo ( Height = sz.Height + Padding.Vertical;)
— Igor Brejc

6

Eu tive que encontrar uma solução rápida, então apenas usei um TextBox com essas propriedades:

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

Essa é uma boa solução, mas talvez eu prefira usar o ReadOnly para definir Enabled como false.
— PahJoker

1
Essa é uma solução criativa que também funciona bem no Compact Framework (onde o Label não possui propriedades AutoSize e MaximumSize).
— Tim Coulter

3

Tenha um melhor com base na resposta 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; isso permite que você use a etiqueta de crescimento automático quando acoplada a um pai, por exemplo, um painel.

this.Height = sz.Height + Padding.Bottom + Padding.Top; aqui cuidamos do preenchimento da parte superior e inferior.


1
  1. Coloque a etiqueta dentro de um painel
  2. Manuseie o ClientSizeChanged eventpara o painel, fazendo com que a etiqueta preencha o espaço:

    private void Panel2_ClientSizeChanged(object sender, EventArgs e)
    {
        label1.MaximumSize = new Size((sender as Control).ClientSize.Width - label1.Left, 10000);
    }
  3. Defina Auto-Sizepara o rótulo comotrue

  4. Defina Dockpara o rótulo comoFill

As etapas 3 e 4 são executadas no designer? Alguma razão pela qual eles são os passos 3 e 4?
— Rabino Stealth

Eles são feitos no designer (mas podem ser feitos no código, se você precisar) e não há motivo para o pedido.
— Noelicus

1

Não tenho certeza que vai caber todos os casos de uso, mas muitas vezes eu uso um truque simples para obter o comportamento de acondicionamento: colocar o seu Labelcom AutoSize=falsedentro de um 1x1 TableLayoutPanelque vai cuidar do Label's tamanho.


1

Defina a propriedade AutoEllipsis como 'TRUE' e a propriedade AutoSize como 'FALSE'.

insira a descrição da imagem aqui

insira a descrição da imagem aqui


0

Se o seu painel estiver limitando a largura do seu rótulo, você poderá definir a propriedade Âncora do rótulo como Esquerda, Direita e definir AutoSize como true. É conceitualmente semelhante a ouvir o SizeChangedevento do Painel e atualizar o MaximumSize do rótulo para um new Size(((Control)sender).Size.Width, 0)como sugerido por uma resposta anterior . Todos os lados listados na propriedade Anchor estão bem ancorados no respectivo lado interno do controle. Portanto, listar dois lados opostos no Anchor efetivamente define a dimensão do controle. Ancoragem para esquerda e direita define a propriedade Largura do controle e Ancoragem para superior e inferior deve definir sua propriedade Altura.

Esta solução, como C #:

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

Não funciona O Label aumenta a largura do meu painel apenas para que ele não precise ser quebrado. Infelizmente, a janela não é tão larga.
— ygoe 24/08/2015

0

Se você realmente deseja definir a largura do rótulo independente do conteúdo, acho que a maneira mais fácil é a seguinte:

  • Definir autosize true
  • Defina a largura máxima como você deseja
  • Definir largura mínima de forma idêntica

Agora, o rótulo tem largura constante, mas adapta sua altura automaticamente.

Em seguida, para texto dinâmico, diminua o tamanho da fonte. Se necessário, use este snippet na sub onde o texto do rótulo está definido:

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

Isso me ajudou em meu formulário chamado 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 inteiro do meu formulário


0

Se as dimensões do botão precisarem ser mantidas inalteradas:

myButton.Text = "word\r\nwrapped"

0

A resposta simples para esse problema é alterar a propriedade DOCK do Label. É "NENHUM" por padrão.


0

Se você estiver inserindo texto no rótulo com antecedência, poderá fazer isso.

  1. No designer, clique com o botão direito do mouse no rótulo e clique em Propriedades.
  2. Em Propriedades, procure a guia de texto.
  3. Clique na guia e clique no botão de seta ao lado.
  4. Uma caixa será exibida em cima dela.
  5. Você pode pressionar enter na caixa pop-up para adicionar linhas e digitar como no bloco de notas! (PRESSIONE ENTRE ONDE DESEJA ENVIAR O TEXTO DO RÓTULO)

-12

Use style="overflow:Scroll"no rótulo como no HTML abaixo. Isso adicionará a barra de rolagem no rótulo dentro do painel.

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

3
Votar isso é bom, mas pelo menos diga por que você fez isso. A razão pela qual isso foi recusado é porque um <asp: Label> não é usado no WinForms. Esta resposta é para a plataforma errada.
— theJerm 6/02

4
porque não é asp.net winform
— Trikaldarshi
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.