1.原理:
1)行数:在RichTextBox旁边放一个Label,设置Label字体大小,然后在RichTextBox的TextChaged方法中判断是否换行,换行就重新为Label设值.
2)标尺:在RichTextBox上面放一个Panel,在Panel上面画尺.
代码如下:
1
using System;
2
using System.Collections.Generic;
3
using System.ComponentModel;
4
using System.Drawing;
5
using System.Data;
6
using System.Text;
7
using System.Windows.Forms;
8
9
namespace NumberedTextBox
10
{
11
public partial class NumberedTextBoxUC : UserControl
12
{
13
14
public NumberedTextBoxUC()
15
{
16
InitializeComponent();
17
18
numberLabel.Font = new Font(richTextBox1.Font.FontFamily, richTextBox1.Font.Size + 1.019f);
19
20
}
21
22
int _currentLine = 0;
23
public int CurrentLine
24
{
25
get
26
{
27
return _currentLine;
28
}
29
set
30
{
31
_currentLine = value;
32
}
33
}
34
private void updateNumberLabel()
35
{
36
//we get index of first visible char and number of first visible line
37
Point pos = new Point(0, 0);
38
int firstIndex = richTextBox1.GetCharIndexFromPosition(pos);
39
int firstLine = richTextBox1.GetLineFromCharIndex(firstIndex);
40
41
//now we get index of last visible char and number of last visible line
42
pos.X = ClientRectangle.Width;
43
pos.Y = ClientRectangle.Height;
44
int lastIndex = richTextBox1.GetCharIndexFromPosition(pos);
45
int lastLine = richTextBox1.GetLineFromCharIndex(lastIndex);
46
int myStart = this.richTextBox1.SelectionStart;
47
int myLine = this.richTextBox1.GetLineFromCharIndex(myStart) + 1;
48
pos = richTextBox1.GetPositionFromCharIndex(lastIndex);
49
if (lastIndex > _currentLine||lastIndex<_currentLine)
50
{
51
//finally, renumber label
52
numberLabel.Text = "";
53
for (int i = firstLine; i <= lastLine + 1; i++)
54
{
55
numberLabel.Text += i + 1 + "\n";
56
}
57
}
58
_currentLine = lastIndex;
59
//this is point position of last visible char, we'll use its Y value for calculating numberLabel size
60
61
}
62
63
64
private void richTextBox1_TextChanged(object sender, EventArgs e)
65
{
66
updateNumberLabel();
67
}
68
69
private void richTextBox1_VScroll(object sender, EventArgs e)
70
{
71
//move location of numberLabel for amount of pixels caused by scrollbar
72
int d = richTextBox1.GetPositionFromCharIndex(0).Y % (richTextBox1.Font.Height + 1);
73
numberLabel.Location = new Point(0, d);
74
75
updateNumberLabel();
76
}
77
78
private void richTextBox1_Resize(object sender, EventArgs e)
79
{
80
richTextBox1_VScroll(null, null);
81
}
82
83
private void richTextBox1_FontChanged(object sender, EventArgs e)
84
{
85
updateNumberLabel();
86
richTextBox1_VScroll(null, null);
87
}
88
89
90
}
91
}
92

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

1
using System;
2
using System.Collections.Generic;
3
using System.Text;
4
using System.Drawing;
5
using System.Windows.Forms;
6
7
namespace Yqun.Client.ReportTools
8
{
9
public class RulerPanel:Panel
10
{
11
protected override void OnPaint(PaintEventArgs e)
12
{
13
Graphics g = e.Graphics;
14
int top = 0;
15
int width = e.ClipRectangle.Width;
16
int temHeight = 5;
17
for (int i = 0; i < width-5; )
18
{
19
20
int height = temHeight;
21
int j = i / 5;
22
if (j % 10 == 0)
23
{
24
height = 15;
25
}
26
else if (j % 5 == 0)
27
{
28
height = 10;
29
}
30
Pen p = new Pen(new SolidBrush(Color.Black));
31
p.Width = 1;
32
g.DrawLine(p, i + 5, top, i + 5, top + height);
33
i += 5;
34
}
35
g.Flush();
36
base.OnPaint(e);
37
}
38
}
39
}
40

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

最终实现效果图: