Reputation: 1730
I would like to determine what the best method is for determining the number of displayed (visible due to scrolling) lines on a multiline winforms TextBox
control.
The current method I am using is grossly inaccurate (as are other methods I have tried):
var size = TextRenderer.MeasureText(
textBox.Text, textBox.Font, textBox.ClientSize, TextFormatFlags.TextBoxControl);
int lines = textBox.Lines.Length;
int lineHeight = (size.Height / lines);
// Value assigned to 'lines' does not reflect number of lines displayed:
int lines = (textBox.Height / lineHeight);
The method to calculate number of lines visible must take into account things such as the scroll bars of the text box, and nuances of text box display including lines that would only be partially visible are not displayed.
Any solution will be greatly appreciated!
Update:
Tried the following calculation as suggested, but still remain with inaccurate result:
int lines = (textBox.Height / textBox.Font.Height);
I've made a simple test program, here is a screenshot, both examples above produce similar results:
The calculated number of lines using the either method often does not reflect number of actual lines displayed as the height is increased or decreased.
Upvotes: 2
Views: 1760
Reputation: 915
Use MeasureText to determine the height of a line and ClientSize.Height for the height within the textbox, which is available for drawing the text:
int lineHeight = TextRenderer.MeasureText("X", this.textbox1.Font).Height;
double linesPerPage = 1.0*this.textbox1.ClientSize.Height / lineHeight;
This works in the same way for a RichTextBox.
Upvotes: 3
Reputation: 125342
You can send EM_GETRECT
message to the text box and then divide height of result RECT
to Font.Height
of the text box.
The result tells you how many line can be show in visible area of TextBox
.
const int EM_GETRECT = 0xB2;
[StructLayout(LayoutKind.Sequential)]
struct RECT
{
public int Left, Top, Right, Bottom;
}
[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern IntPtr SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, ref RECT lParam);
And the usage:
var rect = new RECT();
SendMessage(this.textBox1.Handle, EM_GETRECT, IntPtr.Zero, ref rect);
var count = (rect.Bottom - rect.Top)/this.textBox1.Font.Height;
Upvotes: 4
Reputation: 870
Instead of measuring the height of the lines you can do the following:
Lets say h is the height of the "visible" textBox, and H is the height of the whole text box. Lets call l the number of visible lines, and L the number of lines on total.
We can calculate the ratio h/H. I reckon that the same ratio would hold for the number of lines as well. So h/H should be equal to l/L. You have h H L and you need l.
Upvotes: 0