通過:dataGridView1.TopLeftHeaderCell.Value = "表頭\n回車";設置表頭。
DataGridView實現多維表頭
在做信息管理系統時,很多中式報表都是多維的,要實現報表數據顯示,通常要用到多維表頭。然而,非常遺憾的是,Winform中DataGrid、DataGridView本身不提供多維表頭設計,要實現多維報表只好利用第三方的控件。通過對DataGridView的擴展,利用標題行進行重繪,可實現多維表頭的友好界面。下面是對多維表頭的探討和實現。
1、常用多表頭制作方法
a.第三方控件實現多維表頭:FlexGrid--展示效果很好,就是數據量大加載時顯示速度較慢。
b.報表方式實現多維表頭:CrystalReport、Grid++Report--通過預覽方式實現數據顯示
c、DataGridView實現多維表頭
2、DataGridView多維表頭實現原理
通過重繪標題欄進行多欄實現,通過RowSpan和ColSpan來進行合並,類似Html的Table實現方式。
3、調用方法
private
void Form1_Load(
object sender, EventArgs e)
{
InitDataTable();
InitDataGridView();
}
DataTable table = new DataTable();
private void InitDataTable()
{
DataColumn col;
col = new DataColumn();
col.ColumnName = " 客戶名稱 ";
table.Columns.Add(col);
col = new DataColumn();
col.ColumnName = " 產品名稱 ";
table.Columns.Add(col);
col = new DataColumn();
col.ColumnName = " 規格 ";
table.Columns.Add(col);
col = new DataColumn();
col.ColumnName = " 單位 ";
table.Columns.Add(col);
col = new DataColumn();
col.ColumnName = " 期初存貨數量 ";
col.DataType = System.Type.GetType( " System.Decimal ");
table.Columns.Add(col);
col = new DataColumn();
col.ColumnName = " 期初貨款 ";
col.DataType = System.Type.GetType( " System.Decimal ");
table.Columns.Add(col);
col = new DataColumn();
col.ColumnName = " 期初帳款 ";
col.DataType = System.Type.GetType( " System.Decimal ");
table.Columns.Add(col);
col = new DataColumn();
col.ColumnName = " 發貨數量 ";
col.DataType = System.Type.GetType( " System.Decimal ");
table.Columns.Add(col);
col = new DataColumn();
col.ColumnName = " 發貨金額 ";
col.DataType = System.Type.GetType( " System.Decimal ");
table.Columns.Add(col);
col = new DataColumn();
col.ColumnName = " 開票數量 ";
col.DataType = System.Type.GetType( " System.Decimal ");
table.Columns.Add(col);
col = new DataColumn();
col.ColumnName = " 開票金額 ";
col.DataType = System.Type.GetType( " System.Decimal ");
table.Columns.Add(col);
col = new DataColumn();
col.ColumnName = " 回款數量 ";
col.DataType = System.Type.GetType( " System.Decimal ");
table.Columns.Add(col);
col = new DataColumn();
col.DataType = System.Type.GetType( " System.Decimal ");
col.ColumnName = " 回款金額 ";
table.Columns.Add(col);
col = new DataColumn();
col.DataType = System.Type.GetType( " System.Decimal ");
col.ColumnName = " 未開票回款數量 ";
table.Columns.Add(col);
col = new DataColumn();
col.DataType = System.Type.GetType( " System.Decimal ");
col.ColumnName = " 未開票回款金額 ";
table.Columns.Add(col);
col = new DataColumn();
col.DataType = System.Type.GetType( " System.Decimal ");
col.ColumnName = " 期末存貨數量 ";
table.Columns.Add(col);
col = new DataColumn();
col.DataType = System.Type.GetType( " System.Decimal ");
col.ColumnName = " 期末應收貨款 ";
table.Columns.Add(col);
col = new DataColumn();
col.DataType = System.Type.GetType( " System.Decimal ");
col.ColumnName = " 期末應收帳款 ";
table.Columns.Add(col);
}
private void InitDataGridView()
{
MutilGridHeader topRow = new MutilGridHeader();
topRow.SetRowCol( 3, 18);
// 第一行
topRow.Cells[ 0][ 0].Value = " 客戶 ";
topRow.Cells[ 0][ 0].RowSpan = 3;
topRow.Cells[ 0][ 1].Value = " 產品名稱 ";
topRow.Cells[ 0][ 1].RowSpan = 3;
topRow.Cells[ 0][ 2].Value = " 規格 ";
topRow.Cells[ 0][ 2].RowSpan = 3;
topRow.Cells[ 0][ 3].Value = " 單位 ";
topRow.Cells[ 0][ 3].RowSpan = 3;
topRow.Cells[ 0][ 4].Value = " 期初 ";
topRow.Cells[ 0][ 4].ColSpan = 3;
topRow.Cells[ 0][ 7].Value = " 本期 ";
topRow.Cells[ 0][ 7].ColSpan = 8;
topRow.Cells[ 0][ 15].Value = " 期末 ";
topRow.Cells[ 0][ 15].ColSpan = 3;
// 第二行
topRow.Cells[ 1][ 4].Value = " 存貨數量 ";
topRow.Cells[ 1][ 4].RowSpan = 2;
topRow.Cells[ 1][ 5].Value = " 應收貨款 ";
topRow.Cells[ 1][ 5].RowSpan = 2;
topRow.Cells[ 1][ 6].Value = " 應收帳款 ";
topRow.Cells[ 1][ 6].RowSpan = 2;
topRow.Cells[ 1][ 7].Value = " 發貨 ";
topRow.Cells[ 1][ 7].ColSpan = 2;
topRow.Cells[ 1][ 9].Value = " 開票 ";
topRow.Cells[ 1][ 9].ColSpan = 2;
topRow.Cells[ 1][ 11].Value = " 回款 ";
topRow.Cells[ 1][ 11].ColSpan = 2;
topRow.Cells[ 1][ 13].Value = " 未開票回款 ";
topRow.Cells[ 1][ 13].ColSpan = 2;
topRow.Cells[ 1][ 15].Value = " 存貨數量 ";
topRow.Cells[ 1][ 15].RowSpan = 2;
topRow.Cells[ 1][ 16].Value = " 應收貨款 ";
topRow.Cells[ 1][ 16].RowSpan = 2;
topRow.Cells[ 1][ 17].Value = " 應收票款 ";
topRow.Cells[ 1][ 17].RowSpan = 2;
// 第三行
topRow.Cells[ 2][ 7].Value = " 數量 ";
topRow.Cells[ 2][ 8].Value = " 金額 ";
topRow.Cells[ 2][ 9].Value = " 數量 ";
topRow.Cells[ 2][ 10].Value = " 金額 ";
topRow.Cells[ 2][ 11].Value = " 數量 ";
topRow.Cells[ 2][ 12].Value = " 金額 ";
topRow.Cells[ 2][ 13].Value = " 數量 ";
topRow.Cells[ 2][ 14].Value = " 金額 ";
dataGridViewEx1.Header = topRow;
dataGridViewEx1.DataSource = table;
table.DefaultView.AllowNew = false;
dataGridViewEx1.Columns[ 0].Width = 120;
dataGridViewEx1.Columns[ 1].Width = 100;
dataGridViewEx1.Columns[ 2].Width = 80;
for( int i = 2;i< 18;i++)
dataGridViewEx1.Columns[i].Width = 60;
}
{
InitDataTable();
InitDataGridView();
}
DataTable table = new DataTable();
private void InitDataTable()
{
DataColumn col;
col = new DataColumn();
col.ColumnName = " 客戶名稱 ";
table.Columns.Add(col);
col = new DataColumn();
col.ColumnName = " 產品名稱 ";
table.Columns.Add(col);
col = new DataColumn();
col.ColumnName = " 規格 ";
table.Columns.Add(col);
col = new DataColumn();
col.ColumnName = " 單位 ";
table.Columns.Add(col);
col = new DataColumn();
col.ColumnName = " 期初存貨數量 ";
col.DataType = System.Type.GetType( " System.Decimal ");
table.Columns.Add(col);
col = new DataColumn();
col.ColumnName = " 期初貨款 ";
col.DataType = System.Type.GetType( " System.Decimal ");
table.Columns.Add(col);
col = new DataColumn();
col.ColumnName = " 期初帳款 ";
col.DataType = System.Type.GetType( " System.Decimal ");
table.Columns.Add(col);
col = new DataColumn();
col.ColumnName = " 發貨數量 ";
col.DataType = System.Type.GetType( " System.Decimal ");
table.Columns.Add(col);
col = new DataColumn();
col.ColumnName = " 發貨金額 ";
col.DataType = System.Type.GetType( " System.Decimal ");
table.Columns.Add(col);
col = new DataColumn();
col.ColumnName = " 開票數量 ";
col.DataType = System.Type.GetType( " System.Decimal ");
table.Columns.Add(col);
col = new DataColumn();
col.ColumnName = " 開票金額 ";
col.DataType = System.Type.GetType( " System.Decimal ");
table.Columns.Add(col);
col = new DataColumn();
col.ColumnName = " 回款數量 ";
col.DataType = System.Type.GetType( " System.Decimal ");
table.Columns.Add(col);
col = new DataColumn();
col.DataType = System.Type.GetType( " System.Decimal ");
col.ColumnName = " 回款金額 ";
table.Columns.Add(col);
col = new DataColumn();
col.DataType = System.Type.GetType( " System.Decimal ");
col.ColumnName = " 未開票回款數量 ";
table.Columns.Add(col);
col = new DataColumn();
col.DataType = System.Type.GetType( " System.Decimal ");
col.ColumnName = " 未開票回款金額 ";
table.Columns.Add(col);
col = new DataColumn();
col.DataType = System.Type.GetType( " System.Decimal ");
col.ColumnName = " 期末存貨數量 ";
table.Columns.Add(col);
col = new DataColumn();
col.DataType = System.Type.GetType( " System.Decimal ");
col.ColumnName = " 期末應收貨款 ";
table.Columns.Add(col);
col = new DataColumn();
col.DataType = System.Type.GetType( " System.Decimal ");
col.ColumnName = " 期末應收帳款 ";
table.Columns.Add(col);
}
private void InitDataGridView()
{
MutilGridHeader topRow = new MutilGridHeader();
topRow.SetRowCol( 3, 18);
// 第一行
topRow.Cells[ 0][ 0].Value = " 客戶 ";
topRow.Cells[ 0][ 0].RowSpan = 3;
topRow.Cells[ 0][ 1].Value = " 產品名稱 ";
topRow.Cells[ 0][ 1].RowSpan = 3;
topRow.Cells[ 0][ 2].Value = " 規格 ";
topRow.Cells[ 0][ 2].RowSpan = 3;
topRow.Cells[ 0][ 3].Value = " 單位 ";
topRow.Cells[ 0][ 3].RowSpan = 3;
topRow.Cells[ 0][ 4].Value = " 期初 ";
topRow.Cells[ 0][ 4].ColSpan = 3;
topRow.Cells[ 0][ 7].Value = " 本期 ";
topRow.Cells[ 0][ 7].ColSpan = 8;
topRow.Cells[ 0][ 15].Value = " 期末 ";
topRow.Cells[ 0][ 15].ColSpan = 3;
// 第二行
topRow.Cells[ 1][ 4].Value = " 存貨數量 ";
topRow.Cells[ 1][ 4].RowSpan = 2;
topRow.Cells[ 1][ 5].Value = " 應收貨款 ";
topRow.Cells[ 1][ 5].RowSpan = 2;
topRow.Cells[ 1][ 6].Value = " 應收帳款 ";
topRow.Cells[ 1][ 6].RowSpan = 2;
topRow.Cells[ 1][ 7].Value = " 發貨 ";
topRow.Cells[ 1][ 7].ColSpan = 2;
topRow.Cells[ 1][ 9].Value = " 開票 ";
topRow.Cells[ 1][ 9].ColSpan = 2;
topRow.Cells[ 1][ 11].Value = " 回款 ";
topRow.Cells[ 1][ 11].ColSpan = 2;
topRow.Cells[ 1][ 13].Value = " 未開票回款 ";
topRow.Cells[ 1][ 13].ColSpan = 2;
topRow.Cells[ 1][ 15].Value = " 存貨數量 ";
topRow.Cells[ 1][ 15].RowSpan = 2;
topRow.Cells[ 1][ 16].Value = " 應收貨款 ";
topRow.Cells[ 1][ 16].RowSpan = 2;
topRow.Cells[ 1][ 17].Value = " 應收票款 ";
topRow.Cells[ 1][ 17].RowSpan = 2;
// 第三行
topRow.Cells[ 2][ 7].Value = " 數量 ";
topRow.Cells[ 2][ 8].Value = " 金額 ";
topRow.Cells[ 2][ 9].Value = " 數量 ";
topRow.Cells[ 2][ 10].Value = " 金額 ";
topRow.Cells[ 2][ 11].Value = " 數量 ";
topRow.Cells[ 2][ 12].Value = " 金額 ";
topRow.Cells[ 2][ 13].Value = " 數量 ";
topRow.Cells[ 2][ 14].Value = " 金額 ";
dataGridViewEx1.Header = topRow;
dataGridViewEx1.DataSource = table;
table.DefaultView.AllowNew = false;
dataGridViewEx1.Columns[ 0].Width = 120;
dataGridViewEx1.Columns[ 1].Width = 100;
dataGridViewEx1.Columns[ 2].Width = 80;
for( int i = 2;i< 18;i++)
dataGridViewEx1.Columns[i].Width = 60;
}
最近把我們的b/s系統,增加智能客戶端的功能。確實智能客戶端是非常好用的東西。可惜winform的控件功能不怎么強大,相比vb差很多啊。比如DataGridView不支持二維表頭,不支持表尾合計,相比之下 web的好辦多了(還是喜歡Web的排版、導航,但喜歡Win的操作性,希望WPF早日流行)。
但是 MIS系統沒有二維表頭確實是客戶不能接受的,嘗試了com控件flexgrid或者開源的SourceGrid3,但都不怎么好用,於是想改造一下DataGridView。我的做法是在CellPainting做手腳。花了一天時間嘗試,只是做出原型,還沒有完善,希望有需要的朋友少走彎路。
1,繼承DataGridView,添加表頭信息類。
2,添加CellPainting,代碼如下:
private
void
DataGridViewEx_CellPainting(
object
sender, DataGridViewCellPaintingEventArgs e)
{
if (e.RowIndex == -1)
{
// int w = dataGridView1.HorizontalScrollingOffset + dataGridView1.TopLeftHeaderCell.Size.Width + dataGridView1.Columns[0].Width + 10;

Rectangle newRect = new Rectangle(e.CellBounds.X + 1,
e.CellBounds.Y + 1, e.CellBounds.Width - 4,
e.CellBounds.Height - 4);
using (
Brush gridBrush = new SolidBrush(this.GridColor),
backColorBrush = new SolidBrush(e.CellStyle.BackColor))
{
using (Pen gridLinePen = new Pen(gridBrush))
{
// Erase the cell.
e.Graphics.FillRectangle(backColorBrush, e.CellBounds);
// Draw the grid lines (only the right and bottom lines;
// DataGridView takes care of the others).
e.Graphics.DrawLine(gridLinePen, e.CellBounds.Left,
e.CellBounds.Bottom - 1, e.CellBounds.Right - 1,
e.CellBounds.Bottom - 1);
if (e.ColumnIndex > -1 && topRow!=null&&topRow.Cells[e.ColumnIndex].ColSpan>1)
{
e.Graphics.DrawLine(gridLinePen, e.CellBounds.Right - 1,
e.CellBounds.Top + e.ClipBounds.Height / 2, e.CellBounds.Right - 1,
e.CellBounds.Bottom);
}
else
{
e.Graphics.DrawLine(gridLinePen, e.CellBounds.Right - 1,
e.CellBounds.Top, e.CellBounds.Right - 1,
e.CellBounds.Bottom);
}
// Draw the inset highlight box.
// e.Graphics.DrawRectangle(Pens.Blue, newRect);
int scale = e.CellBounds.Height/3;
if (e.ColumnIndex > -1 && topRow.Cells[e.ColumnIndex].Text != null)
{
scale= e.CellBounds.Height / 2;
e.Graphics.DrawLine(gridLinePen, e.CellBounds.Left, e.CellBounds.Bottom - e.CellBounds.Height / 2, e.CellBounds.Right, e.CellBounds.Bottom - e.CellBounds.Height / 2);
}
// Draw the text content of the cell, ignoring alignment.

if (e.Value != null)
{
e.Graphics.DrawString(e.Value.ToString(), e.CellStyle.Font,
Brushes.Crimson, e.CellBounds.X + 2,
e.CellBounds.Y + scale+ 2, StringFormat.GenericDefault);


}



if (e.ColumnIndex > -1 && topRow.Cells[e.ColumnIndex].RelateIndex > -1 && topRow.Cells[e.ColumnIndex].Text!=null)
{
Rectangle recCell = new Rectangle(e.CellBounds.X - 1 - topRow.Cells[e.ColumnIndex].SpanRowWith,
e.CellBounds.Y + 1, topRow.Cells[e.ColumnIndex].SpanRowWith,
e.CellBounds.Height / 2);

StringFormat sf = new StringFormat();
sf.Alignment = StringAlignment.Center;

e.Graphics.DrawString(topRow.Cells[e.ColumnIndex].Text, e.CellStyle.Font, Brushes.Crimson, recCell, sf);
}
e.Handled = true;
}
}
}
}
3,調用方法
dataGridViewEx1.TopRow.Cells[
2
].Text
=
"
入庫
"
;
dataGridViewEx1.TopRow.Cells[
2
].ColSpan
=
2
;

dataGridViewEx1.TopRow.Cells[
4
].Text
=
"
出庫
"
;
dataGridViewEx1.TopRow.Cells[
4
].ColSpan
=
2
;
至於表尾合計,也做出了原型。二維表頭+表尾合計,基本上滿足需求了。
url: http://greatverve.cnblogs.com/archive/2012/07/17/TopLeftHeaderCell.html
