由於其中要計算單元格文本的顯示寬度,需要使用 Graphics對象,因此這裡使用用戶控件的 CreateGraphics 方法獲得一個 Graphics對象。 Graphics對象不能使用new 語句直接實例化,必須使用某個控件的CreateGraphics方法或從 一個圖片中創建Graphics 對象。現在我們隨著代碼的流程進入到RefreshSize 函數。
在這裡我們定義了一個LeftCount變量,該變量保存了當前表格列的左邊緣位置。定 義了VIEwSize變量,用於保存整個文檔的顯示大小。首先我們需要計算各個表格列的寬度, 由於我們沒有定義表格列對象,因此采用遍歷的手段來獲得所有屬於指定列號的單元格對象 。並設置這些單元格的頂端位置和左端位置。
然後遍歷所有同一列的單元格,計算它 們的文本顯示寬度,並獲得其最大值。則該最大值就是當前表格列的寬度,然後設置這些單 元格的寬度為列寬。並修正整個文檔的顯示大小。
處理了所有的單元格後,文檔視圖 排版完畢,可以顯示了。程序還計算了整個文檔視圖的大小,並根據需要設置控件的 AutoScrollMinSize 屬性用來設置滾動狀態。
UserControl支持自動設置滾動狀態。 當設置用戶控件的AutoScroll屬性時,就啟用自動滾動設置。此時我們可以設置 AutoScrollMinSize屬性來控制滾動狀態,當用戶控件的客戶區ClIEntSize的寬度或高度小於 這個值時就會自動顯示橫向或縱向滾動條,若客戶區大小足夠容納這個AutoScrollMinSize時 ,就不會顯示滾動條,當用戶控件大小改變時會自動進行這樣的判斷。在此我們設置 AutoScrollMinSize為文檔視圖的大小,因此程序也就自動維護滾動狀態。
當程序完 成文檔內容排版後,我們就調用Invalidate函數來通知系統重新繪制控件的用戶界面。
OnPaint
數據加載了,文檔視圖也完成的排版,接下來就是繪制用戶界面了, 我們就很自然的重寫控件的OnPaint函數來繪制網格了。這個方法代碼為
/// <summary>
/// 繪制控件內容
/// </summary>
/// <param name="e">繪制圖形參數</param>
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint (e);
System.Drawing.Rectangle ClipRect = e.ClipRectangle ;
ClipRect.Offset( - this.AutoScrollPosition.X , - this.AutoScrollPosition.Y );
// 進行坐標 轉換
e.Graphics.TranslateTransform( this.AutoScrollPosition.X , this.AutoScrollPosition.Y );
// 繪制網格的畫筆對象
Pen GridPen = null;
if( intGridColor.A != 0 )
{
GridPen = new Pen( intGridColor );
}
// 填充網格的畫刷對象
SolidBrush GridBrush = null;
if( intGridBackColor.A != 0 )
{
GridBrush = new SolidBrush( intGridBackColor );
}
// 繪制文本的畫刷對象
SolidBrush TextBrush = new SolidBrush( this.ForeColor );
// 輸出文本使用的格式化對象
StringFormat TextFormat = new StringFormat();
TextFormat.Alignment = System.Drawing.StringAlignment.Near ;
TextFormat.LineAlignment = System.Drawing.StringAlignment.Center ;
TextFormat.FormatFlags = System.Drawing.StringFormatFlags.NoWrap ;
try
{
foreach( CellRow row in myDocument )
{
foreach( Cell cell in row )
{
// 遍歷所有表格行的單 元格對象,對單元格進行逐個繪制
Rectangle bounds = cell.Bounds ;
// 若單元格和剪切矩形不相交,則單元格無需繪制,轉而處理下一 個單元格.
if( ClipRect.IntersectsWith( bounds ) == false )
{
continue ;
}
if( cell.Selected )
{
// 若單元格處於選擇狀態則顯示高亮度背景色
e.Graphics.FillRectangle( SystemBrushes.Highlight , bounds );
}
else
{
// 繪制單元格背景
if( GridBrush != null )
{
e.Graphics.FillRectangle( GridBrush , bounds );
}
}
if( GridPen != null )
{
// 繪制單元 格邊框
e.Graphics.DrawRectangle( GridPen , bounds );
}
if( cell.Text != null )
{
// 繪制單元格文本
e.Graphics.DrawString(
cell.Text ,
this.Font ,
cell.Selected ? SystemBrushes.HighlightText : TextBrush ,
new RectangleF(
cell.Left ,
cell.Top ,
cell.Width ,
cell.Height ) ,
TextFormat );
}
}
}
}
finally
{
if( GridPen != null )
GridPen.Dispose();
if( GridBrush != null )
GridBrush.Dispose();
TextBrush.Dispose();
TextFormat.Dispose();
}
}