Creating a Windows Forms Label that wraps with C#
One of the few annoyances I occasionally get with C# is the lack
of a word wrap facility for the standard Label
control.
Instead, if the AutoSize
property is set to true
, the label
will just get wider and wider. In order to wrap it, you have to
disable auto resize then manually ensure the height of the label
is sufficient.
The base Control
class has method named GetPreferredSize
which is overridden by derived classes. This method will
calculate the size of a control based on a suggested value. By
calling this method and overriding the OnTextChanged
and
OnResize
methods, we can very easily create a custom label
that automatically wraps and resizes itself vertically to fit
its contents.
Paste in the following code into a new Component to have a read-to-run wrappable label.
using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
namespace Cyotek.Windows.Forms
{
public partial class WrapLabel : Label
{
public WrapLabel()
{
this.AutoSize = false;
}
protected override void OnResize(EventArgs e)
{
base.OnResize(e);
this.FitToContents();
}
protected override void OnTextChanged(EventArgs e)
{
base.OnTextChanged(e);
this.FitToContents();
}
protected virtual void FitToContents()
{
Size size;
size = this.GetPreferredSize(new Size(this.Width, 0));
this.Height = size.Height;
}
[DefaultValue(false), Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public override bool AutoSize
{
get { return base.AutoSize; }
set { base.AutoSize = value; }
}
}
}
So, what is the code doing? It's very straightforward.
In the constructor, we are disabling the built in auto resize functionality, otherwise you won't be able to resize the control in the designer.
Next, we want to override the OnTextChanged
and OnResize
methods to call our new resize functionality. By overriding
these, we can ensure that the control will correctly resize as
required.
Now to implement the actual resize functionality. The
FitToContents
method calls the label's GetPreferredSize
method, passing in the width of the control. This method returns
a Size
structure which is large enough to hold the entire
contents of the control. We take the Height of this (but not the
width) and apply it to the label to make it resize vertically.
When calling GetPreferredSize
, the size we passed in only
had the width specified, which will be the maximum width
returning. As we passed in zero for the height, the method
defines its own maximum height.
Finally, you'll note that we have overridden the AutoSize
property itself and added a number of attributes to it to make
sure it doesn't appear in any property or code windows, and to
prevent its value from being serialized.
Update History
- 2010-05-21 - First published
- 2020-11-21 - Updated formatting
Leave a Comment
While we appreciate comments from our users, please follow our posting guidelines. Have you tried the Cyotek Forums for support from Cyotek and the community?
Comments
Aaron
#
Thanks, looking for this.
You do know "this." is optional, right?
Richard Moss
#
Aaron,
Yes, of course "this" is optional. However, and especially when mixing with "base", I like to be explicit, then the reader should have no difficulty in understanding my meaning. Sometimes I forget though :)
Regards;
[Now I wish we'd built a "reply" functionality into this comment system]
Jim
#
This is exactly what I was looking for. And it works, too. Thanks for the post!
BTW - I completely agree with using 'this' and 'base'. Readability is definitely improved.
Exorsus
#
Whatever you do, there is always someone who tells you ... you are an idiot ... for example some people are using automatic code cleanup using tools like ReSharper and StyleCop so adding base and they can use this explicitly.
Peter
#
Very nice example and explanation but I have one problem. If I drag the wraplabel to a form I can not change the size. I first have to run it and stop the program and after this first run I can change the size on the form.