筆者最近在打造自己的博客自動發布程序,其中設計到編輯器的代碼編寫。一個基本的web編輯器包括所見即所得編輯器、源代碼編輯器、以及預覽部分。基本UI如下圖:
在xhtml編輯器部分需要richtextbox帶有顯示行號和代碼高亮的功能。於是google之,網上資源豐富,筆者在參考權衡之後決定使用c#寫帶行號的richTextBox 一文中的代碼。不過在調試的時候卻出了一點問題。
代碼是正確的,但是卻怎麼也顯示不了頭6行的行號。筆者非常納悶,發現richtextbox控件GetCharIndexFromPosition函數無法正確返回字符索引這個缺陷所致。於是,再仔細查看代碼,將原代碼中第一行
Point p = this.richTextBox1.Location;
修改為
Point p = new Point(0,0);
在此編譯後就正確了。
下面給出完整代碼:
private void ShowNumLines()
{
Point p = new Point(0, 0); 僅修改此行,其余請參考原文
int curIndex = this.rtbox_xhtml.GetCharIndexFromPosition(p);
int curLine = this.rtbox_xhtml.GetLineFromCharIndex(curIndex);
Point curPos = this.rtbox_xhtml.GetPositionFromCharIndex(curIndex);
p.Y += this.rtbox_xhtml.Height;
int curLastIndex = this.rtbox_xhtml.GetCharIndexFromPosition(p);
int curLastLine = this.rtbox_xhtml.GetLineFromCharIndex(curLastIndex);
Point curLastPos = this.rtbox_xhtml.GetPositionFromCharIndex(curLastIndex);
Graphics g = this.xhtml_lines.CreateGraphics();
Font font = new Font(this.rtbox_xhtml.Font, this.rtbox_xhtml.Font.Style);
SolidBrush brush = new SolidBrush(SystemColors.ControlDark);
Rectangle rect = this.xhtml_lines.ClientRectangle;
brush.Color = this.xhtml_lines.BackColor;
g.FillRectangle(brush, 0, 0, this.xhtml_lines.ClientRectangle.Width, this.xhtml_lines.ClientRectangle.Height);
brush.Color = SystemColors.ControlDark;
//
//繪制行號
int lineSpace = 0;
if (curLine != curLastLine)
{
lineSpace = (curLastPos.Y - curPos.Y) / (curLastLine - curLine);
}
else
{
lineSpace = Convert.ToInt32(this.rtbox_xhtml.Font.Size);
}
int brushX = this.xhtml_lines.ClientRectangle.Width - Convert.ToInt32(font.Size * 3);
int brushY = curLastPos.Y + Convert.ToInt32(font.Size * 0.18f);//驚人的算法啊!!
for (int i = curLastLine; i >= curLine; i--)
{
g.DrawString((i + 1).ToString(), font, brush, brushX, brushY);
brushY -= lineSpace;
}
g.Dispose();
font.Dispose();
brush.Dispose();
}