views:

238

answers:

4

I have created a textbox in a Windows Forms application that starts out at a height for entering text in a single line. But I would like the textbox to automatically increase its height if the user enters text that is wrapped within the control.

Currently, for this textbox, I have the properties multiline and wordwrap set to true. I've tried using the TextChanged event to determine when the text has been wrapped but I'm unable to find any property that will help me with this. The Lines property does not provide any help with wrapped text; only for text that the user has hit enter to begin a new line.

How can I get my textbox to expand its height each time the text wraps past the width of the textbox?

A: 

Unfortunately, I can't provide specifics but you are going to need to probably do a custom implementation.

I'd derive a new text box type -- ExpandableTextBox -- and then you'll need to implement it by hand.

This also seems relevant to what you are looking for: http://social.msdn.microsoft.com/Forums/en-US/winforms/thread/11dfb280-b113-4ddf-ad59-788f78d2995a

Frank V
A: 

If you're willing to use a RichTextBox instead (which, in my experience, is kind of a grumpy control that comes with lots of quirks), you can use the ContentsResized event, which gives you the new required size:

private void HandleContentsResized(object sender, ContentsResizedEvenetArgs e)
{
    int newheight = e.NewRectangle.Height;
}
jean
+1  A: 

I just wrote this for a label control for a different project. I got the code off of code project somewhere I think. Changing it to a Textbox should be as simple as changing the base.

public class GrowLabel : Label
{
    private bool _growing;
    //public bool GrowFontSize { get; set; }

    public GrowLabel()
    {
        AutoSize = false;
        //GrowFontSize = false;
    }

    public override sealed bool AutoSize
    {
        get { return base.AutoSize; }
        set { base.AutoSize = value; }
    }

    private void ResizeLabel()
    {
        if (_growing) return;
        try
        {
            _growing = true;

            var sz = new Size(Width, Int32.MaxValue);
            sz = TextRenderer.MeasureText(Text, Font, sz, TextFormatFlags.WordBreak);
            Height = sz.Height;
        }
        finally
        {
            _growing = 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();
    }
}
AdamSane
Thanks, AdamSane, this was a really good answer too. I found Andy's to be simpler and used it instead.
Stephen Fletcher
+1  A: 

Same kind of idea as others have posted, put this in your textChanged event:

Dim s As SizeF = TextRenderer.MeasureText(txt.Text, txt.Font, txt.ClientRectangle.Size, TextFormatFlags.WordBreak)
txt.Height = CInt(s.Height)

You will need some kind of minimum height, and possibly to specify some padding, but this does work.

Pondidum
Great answer and I will use this in my project. Thanks!
Stephen Fletcher