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 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
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 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
最终实现效果图: