我们在使用到WINFORM窗体工作中,要求RichTextBox 加入行号;
之前有看到大牛们写的,但是太复杂繁多,而且有用双TextBox进行联动,非常不错,今天我们尝试RichTextBox +Panel相互联动如下效果.
左侧灰色为Panel,右侧为RichTextBox 控件
1:准备Panel画布如下代码,当接到文件字符后进行坐标解析,绘制行号。

1 private void showLineNo() 2 { 3 //获得当前坐标信息 4 Point p = this.txtFileView.Location; 5 int crntFirstIndex = this.txtFileView.GetCharIndexFromPosition(p); 6 7 int crntFirstLine = this.txtFileView.GetLineFromCharIndex(crntFirstIndex); 8 9 Point crntFirstPos = this.txtFileView.GetPositionFromCharIndex(crntFirstIndex); 10 11 p.Y += this.txtFileView.Height; 12 13 int crntLastIndex = this.txtFileView.GetCharIndexFromPosition(p); 14 15 int crntLastLine = this.txtFileView.GetLineFromCharIndex(crntLastIndex); 16 Point crntLastPos = this.txtFileView.GetPositionFromCharIndex(crntLastIndex); 17 18 //准备画图 19 Graphics g = this.panel2.CreateGraphics(); 20 21 Font font = new Font(this.txtFileView.Font, this.txtFileView.Font.Style); 22 23 SolidBrush brush = new SolidBrush(Color.Green); 24 25 //画图开始 26 27 //刷新画布 28 29 Rectangle rect = this.panel2.ClientRectangle; 30 brush.Color = this.panel2.BackColor; 31 32 g.FillRectangle(brush, 0, 0, this.panel2.ClientRectangle.Width, this.panel2.ClientRectangle.Height); 33 34 brush.Color = Color.White;//重置画笔颜色 35 36 //绘制行号 37 38 int lineSpace = 0; 39 40 if (crntFirstLine != crntLastLine) 41 { 42 lineSpace = (crntLastPos.Y - crntFirstPos.Y) / (crntLastLine - crntFirstLine); 43 44 } 45 46 else 47 { 48 lineSpace = Convert.ToInt32(this.txtFileView.Font.Size); 49 50 } 51 int brushX = this.panel2.ClientRectangle.Width - Convert.ToInt32(font.Size * 3); 52 53 int brushY = crntLastPos.Y + Convert.ToInt32(font.Size * 0.21f); 54 for (int i = crntLastLine; i >= crntFirstLine; i--) 55 { 56 57 g.DrawString((i + 1).ToString(), font, brush, brushX, brushY); 58 59 brushY -= lineSpace; 60 } 61 62 g.Dispose(); 63 64 font.Dispose(); 65 66 brush.Dispose(); 67 }
2:事件准备(启用)如下事件
控件加载事件

1 private void txtFileView_TextChanged(object sender, EventArgs e) 2 { 3 showLineNo(); 4 }
控件滚动事件(当算出的行数大于本控件长度)

1 private void txtFileView_VScroll(object sender, EventArgs e) 2 { 3 showLineNo(); 4 }
完成后,直接启用运行,Demo事例中的效果就出来,方便大家用于各种应用上.