I need a way to determine the size of displayed text in a multi-column TextBox
to set the Scrollbars
property to the correct value.
Since it is some sort of enhanced MessageBox
what I work on, the size of the MessageBox
should be determined from the height and the width of the text sourced by strings with newlines in it.
Currently I use this code to determine the si开发者_开发技巧ze of the MessageBox
depending on the text to be entered. But you see the MessageBox
has a MaximiumSize
determined. The TextBox for the text itself has WordWrap
enabled, too. So the only thing undefined is the Height
of the text after inserting it to TextBox.Text.
SizeF textSize = this.tbxText.CreateGraphics().MeasureString(message, this.tbxText.Font);
int frmWidth = picWidth + (int)textSize.Width;
if (frmWidth > this.MaximumSize.Width)
{
frmWidth = this.MaximumSize.Width;
}
else if (frmWidth < this.MinimumSize.Width)
{
frmWidth = this.MinimumSize.Width;
}
int frmHeight = picHeight + (int)textSize.Height + pnlButtons.Height + pnlInput.Height;
if (frmHeight > this.MaximumSize.Height)
{
frmHeight = this.MaximumSize.Height;
}
else if (frmHeight < this.MinimumSize.Height)
{
frmHeight = this.MinimumSize.Height;
}
Setting the TextBox.Scrollbars
Property to Both as default lets a disabled Scrollbar on the screen that is not really nice nor wanted.
Sadly, the Graphics.MeasureString
does not help really, since it does not consider WordWrap
behaviour.
So, how can I determine if the TextBox.Text
is leaving the visible area making a vertical Scrollbar needed?
I would continue to use Graphics.MeasureString
, but you need to add logic that will simulate a word wrap by dividing the resulting string width with the control width (ie, you calculate how textbox widths fit in your string width) to get your rows and then multply the string height by this.
Note however that Graphics.MeasureString is not entirely accurate, however as a rough guess for scrolling support it might suffice - as always, test this out.
Seems pretty simple, using a RichTextBox
that has pretty different features, such as Scrollbars
that are only displayed if needed and not displayed disabled like on the normal TextBox
.
With the RichTextBox
I can just set the ScrollBars
Property to both and it will manage that right.
Some controls have AutoSize property who shrink/grow by size of controls inside or by text , maybe you don't need to calculate.
One of Graphics.MeasureString
overloads takes a width
argument, (maximum width of the string in pixels).
So, the size needed to render the message in the above example might be:
SizeF textSize = this.tbxText.CreateGraphics()
.MeasureString(message, this.tbxText.Font, this.tbxText.Width);
...
For other Graphics.MeasureString
overloads, see: MeasureString overloads (MSDN)
I just ran into this problem. I had a UserControl with a text-box that I wanted to display without scroll bars, no matter what size it ended up. (That particular user-control is a pane in a window, and the window can be either in portrait or landscape orientation, and I didn't want to have two user-controls for each layout -- that seemed dumb.)
This code, in the Load event-handler, did it for me:
int iLine = textbox1.GetLineFromCharIndex(textbox1.TextLength - 1) + 1;
int iHeight = TextRenderer.MeasureText(this.textbox1.Text, this.textbox1.Font).Height;
float fTextHeight = iHeight * ((float)iLine + 0.25f /* fudge factor */);
textbox1.Size = new Size (textbox1.Size.Width, (int)fTextHeight);
This forum post suggested the use of TextRenderer.MeasureText()
.
精彩评论