由於我們已經計算了所有單元格的位置和大小,因此繪制網格的過程不復雜,就 是遍歷所有的單元格,繪制一個矩形邊框和單元格文本而已。
由於這個用戶界面是可 能發生滾動的,形成一種折射效應,繪制時需要進行坐標轉換,這就增加了一些復雜度。程 序首先獲得剪切矩形ClipRect,並進行移位,然後設置圖形繪制對象e.Graphics進行坐標轉 換,然後遍歷所有的單元格對象,針對每一個單元格,若剪切矩形和單元格的邊框相交,則 繪制單元格,否則不繪制該單元格。
單元格對象有一個 Selected 屬性,表示單元格 是否處於選擇狀態,若單元格處於選擇狀態則使用高亮度背景畫刷 SystemBrushes.Highlight繪制單元格背景,否則使用控件的網格背景色繪制單元格背景。然 後使用控件的網格線顏色來繪制單元格的邊框。繪制控件的邊框後使用Graphics的 DrawString成員來繪制單元格文本,而且當單元格處於選擇狀態則使用高系統定義的高亮度 文本顏色,否則使用控件文本顏色。
這裡創建繪制網格的畫筆對象和繪制背景的畫刷 對象時進行了一些判斷,若顏色值的屬性A為0則不創建對象。在C#中使用類型 System.Drawing.Color來表示顏色值,它有4個屬性來表示顏色特性,也就是A,R,G,B四個 屬性值,其中屬性R,G,B分別表示顏色的紅綠藍的顏色分量,而屬性A表示顏色透明度,若A 等於255則表示純色,不透明,若等於0則表示完全透明,此時繪制圖形也就無意義了,若A的 值在1到254之間則表示半透明,這個值越小,顏色就越透明。
鼠標事件處理
用於客戶要求能用鼠標點擊或拖拽操作來選擇單元格,因此我們需要處理控件的鼠標事件來 實現選擇單元格效果。其代碼為
/// <summary>
/// 上一次鼠標 按鍵按下時鼠標光標位置
/// </summary>
private Point LastMousePosition = new Point( -1 , -1);
/// <summary>
/// 處理鼠 標按鍵按下事件
/// </summary>
/// <param name="e"></param>
protected override void OnMouseDown (MouseEventArgs e)
{
base.OnMouseDown (e);
// 鼠標光標位置 坐標轉換
Point p = new Point( e.X , e.Y );
p.Offset( - this.AutoScrollPosition.X , - this.AutoScrollPosition.Y );
LastMousePosition = p ;
Cell[] cells = myDocument.Cells ;
foreach( Cell cell in cells )
{
Rectangle bounds = cell.Bounds ;
bool select = bounds.Contains( p );
if( cell.Selected != select )
{
InvalidateCell( cell );
cell.Selected = select ;
}
}
}
/// <summary>
/// 處理鼠標移動事件
/// </summary>
/// <param name="e"></param>
protected override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove (e);
if( LastMousePosition.X >= 0 )
{
// 鼠標光標位置坐標轉換
Point p = new Point( e.X , e.Y );
p.Offset( - this.AutoScrollPosition.X , - this.AutoScrollPosition.Y );
// 根據 p 和 LastMousePosition 兩點坐標獲得一個矩形選擇區域
Rectangle SelectRect = Rectangle.Empty ;
if( p.X > LastMousePosition.X )
{
SelectRect.X = LastMousePosition.X ;
SelectRect.Width = p.X - LastMousePosition.X ;
}
else
{
SelectRect.X = p.X ;
SelectRect.Width = LastMousePosition.X - p.X ;
}
if( p.Y > LastMousePosition.Y )
{
SelectRect.Y = LastMousePosition.Y ;
SelectRect.Height = p.Y - LastMousePosition.Y ;
}
else
{
SelectRect.Y = p.Y ;
SelectRect.Height = LastMousePosition.Y - p.Y ;
}
foreach( Cell cell in myDocument.Cells )
{
bool flag = SelectRect.IntersectsWith( cell.Bounds );
if( cell.Selected != flag )
{
cell.Selected = flag ;
this.InvalidateCell( cell );
}
}
}
}
/// <summary>
/// 處理鼠標按鍵松開事件
/// </summary>
/// <param name="e"></param>
protected override void OnMouseUp(MouseEventArgs e)
{
base.OnMouseUp (e);
LastMousePosition = new Point( -1 , -1 );
}