最准确的方法来计算winforms TextBox控件中显示的行数

时间:2016-03-13 18:52:49

标签: c# winforms

我想确定在多线winforms TextBox控件上确定显示(由于滚动可见)行数的最佳方法。

我使用的当前方法非常不准确(我尝试的其他方法也是如此):

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);

计算可见行数的方法必须考虑诸如文本框滚动条之类的内容,文本框显示的细微差别(包括仅部分可见的行)不会显示。

任何解决方案都将不胜感激!

更新

按照建议尝试了以下计算,但结果仍然不准确:

int lines = (textBox.Height / textBox.Font.Height);

我做了一个简单的测试程序,这里是截图,上面的两个例子产生了类似的结果:

screenshot of TextBox height calculation results

使用任一方法计算的行数通常不会反映高度增加或减少时显示的实际行数。

3 个答案:

答案 0 :(得分:2)

您可以向文本框发送EM_GETRECT消息,然后将结果RECT的高度除以文本框的Font.Height
结果告诉您可以在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);

用法:

var rect = new RECT();
SendMessage(this.textBox1.Handle, EM_GETRECT, IntPtr.Zero, ref rect);
var count = (rect.Bottom - rect.Top)/this.textBox1.Font.Height;

答案 1 :(得分:2)

使用MeasureText确定行的高度,使用ClientSize.Height确定文本框中的高度,该高度可用于绘制文本:

        int lineHeight = TextRenderer.MeasureText("X", this.textbox1.Font).Height;
        double linesPerPage = 1.0*this.textbox1.ClientSize.Height / lineHeight;

对于RichTextBox,它的工作方式相同。

答案 2 :(得分:0)

您可以执行以下操作,而不是测量线条的高度:

假设 h 是“可见”文本框的高度, H 是整个文本框的高度。让我们调用 l 可见行数, L 总行数。

我们可以计算比率 h / H 。我估计同样的比率也适用于线数。所以 h / H 应该等于 l / L 。你有 h H L ,你需要 l