211

How can one get word wrap functionality for a Label for text which goes out of bounds?

ΩmegaMan
  • 29,542
  • 12
  • 100
  • 122
Nagu
  • 4,954
  • 14
  • 52
  • 67

20 Answers20

390

Actually, the accepted answer is unnecessarily complicated.

If you set the label to AutoSize, it will automatically grow with whatever text you put in it. (This includes vertical growth.)

If you want to make it word wrap at a particular width, you can set the MaximumSize property.

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

Tested and works.

John Gietzen
  • 48,783
  • 32
  • 145
  • 190
  • 12
    If you have the label snap into it's container, you can switch off AutoSize, leave the max size property as it is, and it will word-wrap exactly as we want. KISS at work! – TheBlastOne May 25 '11 at 09:39
  • You can not achieve a fluid width with that solution. – Robin Oct 04 '12 at 14:07
  • 1
    @Sam: Yes you can, you just set the proper "anchor" properties. Have you even tried it? – John Gietzen Oct 09 '12 at 16:49
  • @JohnGietzen I did. Probably we are not talking about the same. I've a label and a panel below this label. Everything should be fluid in width. I want that the panels top is always positioned on the labels bottom. I – Robin Oct 10 '12 at 06:53
  • 1
    Sam: you should be able to set the `Dock` property of both the label and panel to `Top`, instead of my solution. – John Gietzen Oct 24 '12 at 20:06
  • 2
    I have latched on to `OnResize` in the parent and call `myLabel.MaximumSize = new Size(Bounds.Width, 0);` – Chris Morgan Dec 14 '12 at 06:19
  • 1
    My label doen't have the AutoSize and MaximumSize properties, how can I add these properties ? – Bengi Besçeli Apr 14 '15 at 08:05
  • This is working to great effect for me in combination with a TableLayoutPanel and resetting the MaximumSize on Resize of the parent container with a combination of AutoSize and Percentage rows. It seems like the simplest solution for auto-wrapping width-filling auto-height labels. – TheXenocide Jul 02 '18 at 14:59
183

The quick answer: switch off AutoSize.

The big problem here is that the label will not change its height automatically (only width). To get this right you will need to subclass the label and include vertical resize logic.

Basically what you need to do in OnPaint is:

  1. Measure the height of the text (Graphics.MeasureString).
  2. If the label height is not equal to the height of the text set the height and return.
  3. Draw the text.

You will also need to set the ResizeRedraw style flag in the constructor.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Jonathan C Dickinson
  • 7,181
  • 4
  • 35
  • 46
  • 14
    Select the label you're dynamically adding text to. Look at the properties for the label and turn off AutoSize. You will now be able to drag/set the area for the label and it will automatically auto-wrap to stay within those parameters. No need for any additional coding. – madeFromCode Jun 11 '12 at 16:55
  • This is precisely what I was looking for as it pertains to formatting my form with explanatory text that is in a paragraph form. – Philip Brack Oct 23 '17 at 19:25
  • 1
    @madeFromCode You'd need to set the height programmatically if you want the label to expand vertically else your text will be clipped. – Edwin Aug 15 '18 at 10:15
27

In my case (label on a panel) I set label.AutoSize = false and label.Dock = Fill. And the label text is wrapped automatically.

alex555
  • 1,676
  • 4
  • 27
  • 45
  • This makes the label fill the entire form and make it obscure all other controls in the form... That is, it does not seem to work. Are there other requirements such that it will not fill the entire form? – Peter Mortensen Jan 14 '14 at 12:14
  • 6
    the label **is on a panel**, not on the form directly. Therefore the text does not exceed the bounds of the panel – alex555 Jan 14 '14 at 14:19
  • OK, but then wouldn't it obscure all other controls in the panel? – Peter Mortensen Jan 14 '14 at 14:35
  • 2
    What prevents you from creating an extra panel containing only the label? – alex555 Jan 15 '14 at 08:23
  • That seems like some extra layout that should be unnecessary. Surely the label should have its own box rather than needing to be put into another box. – Edwin Aug 15 '18 at 10:06
  • @Edwin - just fyi _"Surely the label should have its own box rather than needing to be put into another box"_ - in other words, a container, which is what a `Panel` is (among other containers). – EdSF Feb 10 '20 at 23:43
24

There is no autowrap property but this can be done programmatically to size it dynamically. Here is one solution:

  • Select the properties of the label

  • AutoSize = True

  • MaximumSize = (Width, Height) where Width = max size you want the label to be and Height = how many pixels you want it to wrap

    Sample Properties

ΩmegaMan
  • 29,542
  • 12
  • 100
  • 122
Sebastian Castaldi
  • 8,580
  • 3
  • 32
  • 24
13

From MSDN, Automatically Wrap Text in Label:

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();
    }
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
hypo
  • 199
  • 4
  • In order to break on characters rather than words (useful when you have long strings without spaces such as file paths), use (TextFormatFlags.WordBreak | TextFormatFlags.TextBoxControl) instead. See the last post in the same MSDN thread. – Ohad Schneider Feb 22 '10 at 13:17
  • 1
    Also, don't forget to include label's top and bottom padding in the calculation (`Height = sz.Height + Padding.Vertical;`) – Igor Brejc Sep 17 '14 at 05:57
8

I had to find a quick solution, so I just used a TextBox with those properties:

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
                    };
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
user3356581
  • 81
  • 1
  • 1
  • 1
    This is a good solution, but I might prefer using ReadOnly to setting Enabled to false. – PahJoker Nov 01 '15 at 01:52
  • 1
    This is an imaginative solution that also works well on Compact Framework (where Label does not have AutoSize and MaximumSize properties). – Tim Coulter May 26 '16 at 08:22
3

Have a better one based on @hypo 's answer

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; this allows you to use auto-grow label when docked to a parent, e.g. a panel.

this.Height = sz.Height + Padding.Bottom + Padding.Top; here we take care of padding for top and bottom.

Neuron
  • 5,141
  • 5
  • 38
  • 59
march1993
  • 133
  • 1
  • 7
2
  1. Put the label inside a panel

  2. Handle the ClientSizeChanged event for the panel, making the label fill the space:

    private void Panel2_ClientSizeChanged(object sender, EventArgs e)
    {
        label1.MaximumSize = new Size((sender as Control).ClientSize.Width - label1.Left, 10000);
    }
    
  3. Set Auto-Size for the label to true

  4. Set Dock for the label to Fill

All but step 2 would typically be done in the designer window.

noelicus
  • 14,468
  • 3
  • 92
  • 111
2

Not sure it will fit all use-cases but I often use a simple trick to get the wrapping behaviour: put your Label with AutoSize=false inside a 1x1 TableLayoutPanel which will take care of the Label's size.

Pragmateek
  • 13,174
  • 9
  • 74
  • 108
1

Set the AutoEllipsis Property to 'TRUE' and AutoSize Property to 'FALSE'.

enter image description here

enter image description here

Ravi Kumar G N
  • 396
  • 1
  • 3
  • 11
0

If your panel is limiting the width of your label, you can set your label’s Anchor property to Left, Right and set AutoSize to true. This is conceptually similar to listening for the Panel’s SizeChanged event and updating the label’s MaximumSize to a new Size(((Control)sender).Size.Width, 0) as suggested by a previous answer. Every side listed in the Anchor property is, well, anchored to the containing Control’s respective inner side. So listing two opposite sides in Anchor effectively sets the control’s dimension. Anchoring to Left and Right sets the Control’s Width property and Anchoring to Top and Bottom would set its Height property.

This solution, as C#:

label.Anchor = AnchorStyles.Left | AnchorStyles.Right;
label.AutoSize = true;
Community
  • 1
  • 1
binki
  • 7,754
  • 5
  • 64
  • 110
  • 1
    Doesn't work. The Label increases the width of my panel just that it doesn't have to wrap. Unfortunately, the window is not as wide. – ygoe Aug 24 '15 at 17:39
0

If you really want to set the label width independent of the content, I find that the easiest way is this:

  • Set autosize true
  • Set maximum width to how you want it
  • Set minimum width identically

Now the label is of constant width, but it adapts its height automatically.

Then for dynamic text, decrease the font size. If necessary, use this snippet in the sub where the label text is set:

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
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
0

This helped me in my Form called 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);
}

Whole code of my form

Mic
  • 105
  • 1
  • 6
0

If the dimensions of the button need to be kept unchanged:

myButton.Text = "word\r\nwrapped"
Cape Code
  • 3,584
  • 3
  • 24
  • 45
rjain
  • 30
  • 3
0

The simple answer for this problem is to change the DOCK property of the Label. It is "NONE" by default.

0

If you are entering text into the label beforehand, you can do this.

  1. In the designer, Right-Click on the label and click Properties.
  2. In Properties, search for text tab.
  3. Click in the tab and click on the arrow button next to it.
  4. A box will popup on top of it.
  5. You can press enter in the popup box to add lines and type as in notepad! (PRESS ENTER WHERE YOU WANT TO WRAP THE LABEL TEXT)
D J
  • 845
  • 1
  • 13
  • 27
0

I would recommend setting AutoEllipsis property of label to true and AutoSize to false. If text length exceeds label bounds, it'll add three dots (...) at the end and automatically set the complete text as a tooltip. So users can see the complete text by hovering over the label.

Usama Aziz
  • 169
  • 1
  • 10
0

I have a label that autowraps and grows to whatever size in a right docked autosize panel, whose width is set by other content.

Label (in tablelayoutpanel) Autosize = True.

TableLayoutPanel (in panel) Autosize = True, AutoSizeMode = GrowAndShrink, Dock = Bottom, one Column SizeType = 100%, one Row SizeType = 100%.

Panel (right docked in form) AutoSize = True, AutoSizeMode = GrowAndShrink, Dock = Right.

ourmandave
  • 1,505
  • 2
  • 15
  • 49
0

Use System.Windows.Forms.LinkLabel instead of Label and set the property LinkArea as below.

myLabel.LinkArea = new LinkArea(0, 0);
-12

Use style="overflow:Scroll" in the label as in the below HTML. This will add the scroll bar in the label within the panel.

<asp:Label
    ID="txtAOI"
    runat="server"
    style="overflow:Scroll"
    CssClass="areatext"
    BackColor="White"
    BorderColor="Gray"
    BorderWidth="1"
    Width = "900" ></asp:Label>
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131