用C#來開發工具有很高的生產力,不過有些功能還是需要自己實作或是要找其它資源作整合。例如TextBox元件就沒有像許多文字編輯器都有的顯示文件行號的功能,這個功能需要自己想辨法。要作到顯示行號,有幾種方法,而下面要介紹的是一個較簡單的實現方法。
基本概念是這樣:
想法很簡單,實作也同樣不難。
在Form放上一個Panel元件,屬性設置如下:
接著放上一個RichTextBox元件,,屬性設置如下:
完成後如下圖所示。
接下來是加上事件的處理。
在TextBox上加上TextChanged和VScroll二個事件處理函式。
當文字內容變更或發生捲動時,重畫在Panel上的行號,反應目前的狀態。
接下來加上Panel的Paint事件處理,在這裡面把行號顯示出來。這部份的處理主要分幾個部份。
底下是部份程式碼。
下圖是程式結果。
(下載範例)
基本概念是這樣:
- 在TextBox左邊加一個Panel元件,在Panel上根據目前TextBox的位置顯示行號在其上
- 每當TextBox內容變更(OnTextChanged)或垂直捲軸發生滾動(OnVScroll)時重畫Panel
想法很簡單,實作也同樣不難。
在Form放上一個Panel元件,屬性設置如下:
- (Name) = panel1
- BorderStyle = None
- Dock = Left
接著放上一個RichTextBox元件,,屬性設置如下:
- (Name) = textBox1
- BorderStyle = None
- Dock = Fill
- WordWrap = False
完成後如下圖所示。
接下來是加上事件的處理。
在TextBox上加上TextChanged和VScroll二個事件處理函式。
private void textBox1_TextChanged(object sender, EventArgs e)
{
panel1.Invalidate();
}
private void textBox1_VScroll(object sender, EventArgs e)
{
panel1.Invalidate();
}
當文字內容變更或發生捲動時,重畫在Panel上的行號,反應目前的狀態。
接下來加上Panel的Paint事件處理,在這裡面把行號顯示出來。這部份的處理主要分幾個部份。
- 計算可見範圍的行號,這樣作是避免作多虛功,只畫需要畫的部份
- 建立一個Off Screen Graphics,先畫在這個緩衝區上,然後再一次貼上畫面,這樣作是為了避免畫面更新如果不夠快的話會造成閃爍
底下是部份程式碼。
private void panel1_Paint(object sender, PaintEventArgs e)
{
//
// Calc number range.
//
int FirstLineIndex = textBox1.GetCharIndexFromPosition(Point.Empty);
int FirstLine = textBox1.GetLineFromCharIndex(FirstLineIndex);
int LastLineIndex = textBox1.GetCharIndexFromPosition(new Point(textBox1.Width, textBox1.Height));
int LastLine = textBox1.GetLineFromCharIndex(LastLineIndex);
int w = Math.Max(FirstLine.ToString().Length, LastLine.ToString().Length);
//
// Create off-screen image.
//
Bitmap img = new Bitmap(panel1.Width, panel1.Height);
Graphics g = Graphics.FromImage(img); // Off-screen image.
...
//
// Draw line numbers.
//
for (int i = FirstLine; i <= LastLine; i++, Pos.Y += H)
{
...
}
//
// Blit.
//
e.Graphics.DrawImage(img, 0, 0);
}
下圖是程式結果。
(下載範例)


留言
張貼留言