2

I am working on a UserControl that contains a multiline TextBox.

When using my control, one will be able to set the text that will be displayed. The TextBox should then adapt its Height to make the text fit, the Width cannot change.

So here is the property that handles the text :

[Editor(typeof(MultilineStringEditor), typeof(UITypeEditor))] public string TextToDisplay { get { return internalTextBox.Text; } set { internalTextBox.Text = value; AdaptTextBoxSize(); } } 

My first attempt was rather simple :

private void AdaptTextBoxSize() { int nbLignes = internalTextBox.Lines.Length; float lineHeight = internalTextBox.Font.GetHeight(); internalTextBox.Height = (int)((nbLignes) * lineHeight); } 

This did not work as it doesn't take into account spacing between two lines of text. So the more lines I have in the text, the more I get clipped.

So I tried this :

private void AdaptTextBoxSize() { Size textSize = internalTextBox.GetPreferredSize(new Size(internalTextBox.Width, 0)); internalTextBox.Height = textSize.Height; } 

This does work when all the lines in the textbox are shorter than the Width. But when one line is longer and should be clipped to the next line, GetPreferredSize() returns a larger width than the one I passed, and therefore the height is too small.

So I changed again and tried this one:

private void AdaptTextBoxSize() { Size textSize = TextRenderer.MeasureText( internalTextBox.Text, internalTextBox.Font, new Size(internalTextBox.Width, 0), TextFormatFlags.WordEllipsis ); internalTextBox.Height = textSize.Height; } 

This time the returned Width is correct, as it does not exceed the one I passed, but the height is the same as the previous trial. So it doesn't work either. I tried different combinations for TextFormatFlags, but could not manage to find the winning one...

Is this a bug from the framework?

The real question here is, is there another thing I can try, or another to achieve what I want (i.e. auto-adapt the height when setting the TextToDisplay property)?

5
  • What is the value of the UseCompatibleTextRendering property? This might be related. Commented Jul 4, 2018 at 10:57
  • @AhmedAbdelhameed Well I tried with the solution in your link but still have the same problem. The values are slightly different but I still have a line that is cut out if one of my lines is too long. Commented Jul 4, 2018 at 11:59
  • Why are you using TextFormatFlags.WordEllipsis? Try simpler solution. Measure text is the right way (no need to put a whole story into question), it should work. I suggest you to post only code with measuring text attempt and screenshot with problem. "the height is the same as the previous trial" might be an interesting, but not really useful observation. Commented Jul 4, 2018 at 12:07
  • 1
    There are known problem with width : here, here. Try using TextFormatFlags.WordBreak (from here), is result different? Commented Jul 4, 2018 at 12:16
  • @Sinatr I actually have no problem measuring width, but with measuring height. My width is fixed but the calculated height doesn't seem to be correct when a line is too long. I'll update my question Commented Jul 4, 2018 at 12:44

1 Answer 1

2

TextBox.GetPositionFromCharIndex returns the pixel position of a character. Position here means top/left so we need to add one more line..

This seems to work here:

textBox.Height = textBox.GetPositionFromCharIndex(textBox4.Text.Length - 1).Y + lineHeight; 

I get the line height like this:

int lineHeight = -1; using (TextBox t = new TextBox() { Font = textBox.Font }) lineHeight = t.Height; 

I set the Height instead of the ClientSize.Height, which is slightly wrong unless BorderStyle is None. You can change to textBox.ClientSize = new Size(textBox.ClientSize.Width, l + lh);

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.