带有行数和标尺的RichTextBox

项目需要一个带有行数和标尺功能的RichTextBox,先是打算在RichTextBox里面自画,但最终没有实现,最终用UserControl实现了该功能.
1.原理:
1)行数:在RichTextBox旁边放一个Label,设置Label字体大小,然后在RichTextBox的TextChaged方法中判断是否换行,换行就重新为Label设值.
2)标尺:在RichTextBox上面放一个Panel,在Panel上面画尺.
代码如下:
 1 None.gif using  System;
 2 None.gif using  System.Collections.Generic;
 3 None.gif using  System.ComponentModel;
 4 None.gif using  System.Drawing;
 5 None.gif using  System.Data;
 6 None.gif using  System.Text;
 7 None.gif using  System.Windows.Forms;
 8 None.gif
 9 None.gif namespace  NumberedTextBox
10 ExpandedBlockStart.gifContractedBlock.gif dot.gif {
11InBlock.gif    public partial class NumberedTextBoxUC : UserControl
12ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
13InBlock.gif
14InBlock.gif        public NumberedTextBoxUC()
15ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
16InBlock.gif            InitializeComponent();
17InBlock.gif
18InBlock.gif            numberLabel.Font = new Font(richTextBox1.Font.FontFamily, richTextBox1.Font.Size + 1.019f);
19InBlock.gif           
20ExpandedSubBlockEnd.gif        }

21InBlock.gif
22InBlock.gif        int _currentLine = 0;
23InBlock.gif        public int CurrentLine
24ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
25InBlock.gif            get
26ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
27InBlock.gif                return _currentLine;
28ExpandedSubBlockEnd.gif            }

29InBlock.gif            set
30ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
31InBlock.gif                _currentLine = value;
32ExpandedSubBlockEnd.gif            }

33ExpandedSubBlockEnd.gif        }

34InBlock.gif        private void updateNumberLabel()
35ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
36InBlock.gif            //we get index of first visible char and number of first visible line
37InBlock.gif            Point pos = new Point(00);
38InBlock.gif            int firstIndex = richTextBox1.GetCharIndexFromPosition(pos);
39InBlock.gif            int firstLine = richTextBox1.GetLineFromCharIndex(firstIndex);
40InBlock.gif
41InBlock.gif            //now we get index of last visible char and number of last visible line
42InBlock.gif            pos.X = ClientRectangle.Width;
43InBlock.gif            pos.Y = ClientRectangle.Height;
44InBlock.gif            int lastIndex = richTextBox1.GetCharIndexFromPosition(pos);
45InBlock.gif            int lastLine = richTextBox1.GetLineFromCharIndex(lastIndex);
46InBlock.gif            int myStart = this.richTextBox1.SelectionStart;
47InBlock.gif            int myLine = this.richTextBox1.GetLineFromCharIndex(myStart) + 1;
48InBlock.gif            pos = richTextBox1.GetPositionFromCharIndex(lastIndex);
49InBlock.gif            if (lastIndex > _currentLine||lastIndex<_currentLine)
50ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
51InBlock.gif                //finally, renumber label
52InBlock.gif                numberLabel.Text = "";
53InBlock.gif                for (int i = firstLine; i <= lastLine + 1; i++)
54ExpandedSubBlockStart.gifContractedSubBlock.gif                dot.gif{
55InBlock.gif                    numberLabel.Text += i + 1 + "\n";
56ExpandedSubBlockEnd.gif                }

57ExpandedSubBlockEnd.gif            }

58InBlock.gif            _currentLine = lastIndex;
59InBlock.gif            //this is point position of last visible char, we'll use its Y value for calculating numberLabel size 
60InBlock.gif
61ExpandedSubBlockEnd.gif        }

62InBlock.gif
63InBlock.gif
64InBlock.gif        private void richTextBox1_TextChanged(object sender, EventArgs e)
65ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
66InBlock.gif            updateNumberLabel();            
67ExpandedSubBlockEnd.gif        }

68InBlock.gif
69InBlock.gif        private void richTextBox1_VScroll(object sender, EventArgs e)
70ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
71InBlock.gif            //move location of numberLabel for amount of pixels caused by scrollbar
72InBlock.gif            int d = richTextBox1.GetPositionFromCharIndex(0).Y % (richTextBox1.Font.Height + 1);
73InBlock.gif            numberLabel.Location = new Point(0, d);
74InBlock.gif
75InBlock.gif            updateNumberLabel();
76ExpandedSubBlockEnd.gif        }

77InBlock.gif
78InBlock.gif        private void richTextBox1_Resize(object sender, EventArgs e)
79ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
80InBlock.gif            richTextBox1_VScroll(nullnull);
81ExpandedSubBlockEnd.gif        }

82InBlock.gif
83InBlock.gif        private void richTextBox1_FontChanged(object sender, EventArgs e)
84ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
85InBlock.gif            updateNumberLabel();
86InBlock.gif            richTextBox1_VScroll(nullnull);
87ExpandedSubBlockEnd.gif        }
            
88InBlock.gif
89InBlock.gif
90ExpandedSubBlockEnd.gif    }

91ExpandedBlockEnd.gif}

92 None.gif
 1 None.gif using  System;
 2 None.gif using  System.Collections.Generic;
 3 None.gif using  System.Text;
 4 None.gif using  System.Drawing;
 5 None.gif using  System.Windows.Forms;
 6 None.gif
 7 None.gif namespace  Yqun.Client.ReportTools
 8 ExpandedBlockStart.gifContractedBlock.gif dot.gif {
 9InBlock.gif    public class RulerPanel:Panel
10ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
11InBlock.gif        protected override void OnPaint(PaintEventArgs e)
12ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
13InBlock.gif            Graphics g = e.Graphics;
14InBlock.gif            int top = 0;
15InBlock.gif            int width = e.ClipRectangle.Width;
16InBlock.gif            int temHeight = 5;
17InBlock.gif            for (int i = 0; i < width-5; )
18ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
19InBlock.gif                
20InBlock.gif                int height = temHeight;
21InBlock.gif                int j = i / 5;
22InBlock.gif                if (j % 10 == 0)
23ExpandedSubBlockStart.gifContractedSubBlock.gif                dot.gif{
24InBlock.gif                    height = 15;
25ExpandedSubBlockEnd.gif                }

26InBlock.gif                else if (j % 5 == 0)
27ExpandedSubBlockStart.gifContractedSubBlock.gif                dot.gif{
28InBlock.gif                    height = 10;
29ExpandedSubBlockEnd.gif                }
               
30InBlock.gif                Pen p = new Pen(new SolidBrush(Color.Black));
31InBlock.gif                p.Width = 1;
32InBlock.gif                g.DrawLine(p, i + 5, top, i + 5, top + height);
33InBlock.gif                i += 5;               
34ExpandedSubBlockEnd.gif            }

35InBlock.gif            g.Flush();
36InBlock.gif            base.OnPaint(e);
37ExpandedSubBlockEnd.gif        }

38ExpandedSubBlockEnd.gif    }

39ExpandedBlockEnd.gif}

40 None.gif

最终实现效果图:
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值