在開發一個基於Window Form的CS應用程序的時候,我搜索過一個這樣 的DataGridView 控件,它能顯示一列內容的總和。例如:統計顧客訂單的總數 ,顯示在Grid中的一列上。就像Excel能做的一樣,我沒有找到一個合適的解決 方案,所以我決定自己開發一個組件。它能像DataGridView一樣工作,能在表格 的底部顯示一行。
為了SummaryRow的重新定位和大小的調整,我重構了一些代碼,代碼借用了 Robert Rhode寫的Nice Filterable DataGrid。
為了能運行 SummaryDataGridViewTest-Application ,必要將Nwind.mdb 數據庫拷貝到輸出 路徑下面。
非常好的DataGridView和Window-Forms類庫的知識有助於你 定制代碼,但是它不是必要的。因為使用SummaryDataGridView 非常的簡單。
SummaryDataGridView 能像任何其他Windows-Forms 控件一樣使用。支 持設計時的設定。在設計上,它有一組公共屬性。使用類似DataGridView ,因 為它是繼承了DataGridView。為了顯示數據,需要設置控件的DataSource 屬性 。每一列必須添加到字符串數組SummaryColumns中。看圖1和圖2的公有屬性,看 他們是如何影響SummaryDataGridView的。
SummaryRow
使用DataGridView 的一行作為總結行是一件非常棘手的事情,會帶來很多問 題。我沒有找到在表格的底部固定SummaryRow的解決方案,它又必須是滾動的。 由於這個原因,我使用一個帶Textboxe的簡單控件,它顯示在DataGridView的下 面。所有的textbox和DataGridView一起改變自己的大小。此外它必須利用自己 的水平滾動條將顯示在我們的SummaryControlContainer下面,而不是使用顯示 在SummaryRow上面的 DataGridView的水平滾動條。因此有相當一部分的代碼是 處理SummaryRow的定位、大小、排序的。總結一行的值是控件中最容易實現的部 分。下面的DataGridView事件的處理是為了使DataGridView和SummaryRow同步:
ColumnAdded, ColumnRemoved, ColumnStateChanged, ColumnDisplayIndexChanged
為了了解更多的關於同步的信息,看這些方法:SummaryControlContainer 類的reCreateSumBoxes() 和resizeSumBoxes() 方法
SummaryRow 和DataGridView粘合:
如何將SummaryRow 附加到DataGridView上面。最簡單的方式是使用一個控件 將SummaryRow 和DataGridView包含在其中。通過一個公共屬性在表格之間訪問 。我決定讓DataGridView創建自己的SummaryRow。為了避免設計時出現的問題, 我們在運行時完成。在DataGridView 初始化之後,調用 ChangeParent() 方法 。這個方法從父控件移除DataGridView ,在這個地方創建一個panel,然後在這 個panel中包含DataGridView 和SummaryRow 。在移除DataGridView之前,我們 必須在TableLayoutPanel上確定確切位置。
private void changeParent()
{
if (!DesignMode && Parent != null)
{
[..]
panel.Bounds = this.Bounds;
panel.BackColor = this.BackgroundColor;
panel.Dock = this.Dock;
[..]
summaryControl.Dock = DockStyle.Bottom;
this.Dock = DockStyle.Fill;
Special handling for TableLayoutPanels
if (this.Parent is TableLayoutPanel)
{
int rowSpan, colSpan;
TableLayoutPanel tlp = this.Parent as TableLayoutPanel;
TableLayoutPanelCellPosition cellPos =
tlp.GetCellPosition(this);
rowSpan = tlp.GetRowSpan (this);
colSpan = tlp.GetColumnSpan (this);
tlp.Controls.Remove(this);
tlp.Controls.Add(panel, cellPos.Column, cellPos.Row);
tlp.SetRowSpan(panel, rowSpan);
tlp.SetColumnSpan(panel, colSpan);
}
else
{
Control parent = this.Parent;
remove DataGridView from ParentControls
parent.Controls.Remove (this);
parent.Controls.Add(panel);
}
summaryControl.Controls.Add (hScrollBar);
hScrollBar.BringToFront();
panel.Controls.Add(this);
panel.Controls.Add(summaryControl);
adjustSumControlToGrid();
adjustScrollbarToSummaryControl();
resizeHScrollBar();
}
}
只讀的TextBox:
一個標准的Windows窗體TextBox,使其ReadOnly屬性設置為true 主要問題是 ,認為該文本框顏色更改為Caption(灰),不能設置其他的顏色。我想讓 SummaryRow 的背景顏色是純白色。這就是為什麼我要包括我自己的TextBox。這 是一個簡單的控件,因為在TextBox中沒有EventHandling。TextBox能獲得 IsSummary屬性來表明是否用來合總。直接在OnPaint事件中繪制控件。
protected override void OnPaint(PaintEventArgs e)
{
Rectangle textBounds;
textBounds = new Rectangle(this.ClientRectangle.X + 2, this.ClientRectangle.Y + 2,
this.ClientRectangle.Width - 2, this.ClientRectangle.Height - 2);
using (Pen pen = new Pen(borderColor))
{
e.Graphics.FillRectangle(new SolidBrush (this.BackColor), this.ClientRectangle);
e.Graphics.DrawRectangle(pen, this.ClientRectangle.X, this.ClientRectangle.Y,
this.ClientRectangle.Width - subWidth, this.ClientRectangle.Height - 1);
e.Graphics.DrawString(Text, Font, Brushes.Black, textBounds, format);
}
}
在公共屬性SumaryRowBackColor中設置SummaryRow的顏色
實際是在calcSummaries()方法中統計列值,這個方法在 DataGridView的 [RowsAdded] [RowsRemoved] 和[CellValueChanged] 事件處理中調用。它通過 遍歷DataGridView 的每一行在SummaryColumn上總計列值
原文: http://www.codeproject.com/KB/grid/Summary_DataGridView.aspx
出處:http://zhuqil.cnblogs.com
本文配套源碼