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.