作ってみました。(いろいろ改善の余地はありそうですが)
UseCompatibleTextRendering = true のときは大丈夫なのですが、
false のときは、テキストをラベルに代入して描画しないと
TextRenderer.MeasureText が正しい値を返さないようです。
C#
1using System;
2using System.Drawing;
3using System.Reflection;
4using System.Text;
5using System.Windows.Forms;
6
7static class UTL
8{
9 // テキストをラベルに表示したときの行数を取得する
10 public static int GetLines(Label label, string text)
11 {
12 // UseCompatibleTextRendering = false のときは、代入しないと正しい値が求まらない
13 label.Text = text;
14 // テキストをラベルに表示したときの高さを取得
15 int textHeight = UTL.GetTextHeight(label, text);
16
17 int lines = 1; // 1行から開始(ここは工夫が必要かも)
18 while (true)
19 {
20 // n行の高さを求める
21 int linesHeight = UTL.GetTextHeight(label, lines);
22 // n行の高さがテキストの高さ以上になったら終了
23 if (linesHeight >= textHeight)
24 {
25 return lines;
26 }
27 lines++;
28 }
29 }
30
31 private static int GetTextHeight(Label label, string text)
32 {
33 Rectangle face = DeflateRect(label.ClientRectangle, label.Padding);
34 using (var g = label.CreateGraphics())
35 {
36 if (label.UseCompatibleTextRendering)
37 {
38 using (StringFormat stringFormat = CreateStringFormat(label))
39 {
40 SizeF size = g.MeasureString(text, label.Font, face.Width, stringFormat);
41 return (int)size.Height;
42 }
43 }
44 else
45 {
46 TextFormatFlags flags = CreateTextFormatFlags(label);
47 Size size = TextRenderer.MeasureText(g, text, label.Font, new Size(face.Width, int.MaxValue), flags);
48 return size.Height;
49 }
50 }
51 }
52
53 private static Rectangle DeflateRect(Rectangle rect, Padding padding)
54 {
55 rect.X += padding.Left;
56 rect.Y += padding.Top;
57 rect.Width -= padding.Horizontal;
58 rect.Height -= padding.Vertical;
59 return rect;
60 }
61
62 private static int GetTextHeight(Label label, int lines)
63 {
64 var sb = new StringBuilder();
65 for (int i = 1; i <= lines; i++)
66 {
67 sb.AppendLine();
68 }
69 return GetTextHeight(label, sb.ToString());
70 }
71
72 // ロジックを転記するのが面倒なのでリフレクションで呼び出す。
73
74 private static StringFormat CreateStringFormat(Label label)
75 {
76 Type type = typeof(Label);
77 MethodInfo mi = type.GetMethod(
78 "CreateStringFormat",
79 BindingFlags.Instance | BindingFlags.NonPublic,
80 null,
81 new Type[0],
82 new ParameterModifier[0]);
83 return (StringFormat)mi.Invoke(label, null);
84 }
85
86 private static TextFormatFlags CreateTextFormatFlags(Label label)
87 {
88 Type type = typeof(Label);
89 MethodInfo mi = type.GetMethod(
90 "CreateTextFormatFlags",
91 BindingFlags.Instance | BindingFlags.NonPublic,
92 null,
93 new Type[0],
94 new ParameterModifier[0]);
95 return (TextFormatFlags)mi.Invoke(label, null);
96 }
97}
#使い方
C#
1 using System;
2 using System.Windows.Forms;
3
4 public partial class Form1 : Form
5 {
6 public Form1()
7 {
8 InitializeComponent();
9 }
10
11 private void checkBox1_CheckedChanged(object sender, EventArgs e)
12 {
13 label1.UseCompatibleTextRendering = ((CheckBox)sender).Checked;
14 textBox1_TextChanged(textBox1, EventArgs.Empty);
15 }
16
17 private void textBox1_TextChanged(object sender, EventArgs e)
18 {
19 int lines = UTL.GetLines(label1, ((TextBox)sender).Text);
20 label2.Text = string.Format("{0}行です。", lines);
21 }
22 }