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?

Nagu
fonte

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.

Jonathan C Dickinson
fonte
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.

John Gietzen
fonte
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.

alex555
fonte
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

Sebastian Castaldi
fonte
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();
    }
}
hipopótamo
fonte
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
                    };
user3356581
fonte
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.

march1993
fonte
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
noelicus
fonte
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.

Pragmateek
fonte
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

Ravi Kumar GN
fonte
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;
binki
fonte
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
Kjell Verbeke
fonte
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

Microfone
fonte
0

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

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

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

Sunil Neeradi
fonte
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)
DJ
fonte
-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>
Sweety Jain
fonte
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