C#中DataGridView多層表頭的制作(1)
先看效果:
1.首先要調整表頭的高度,記得在DataGrid中是沒法調整表頭高度,但DataGridView是可以的.
設定ColumnHeadsHeightSizeMode為EnableResizing或DisableResizing.再設定ColumnHeadersHeight
2.要繪製自已的表頭,必須要得到表頭的寬(由開始列,結束列決定)和高(由總層次,第幾層決定),我用一個類對它做了封裝 :
public class HeaderCell
{
private int startColIndex;
private int endColIndex;
private int deepCount;
private int startDeepIndex;
private int endDeepIndex;
/// <summary>
///
/// </summary>
/// <param name="startColIndex"></param>
/// <param name="endColIndex"></param>
/// <param name="deepCount"></param>
/// <param name="deepIndex">從下往上數,序號從1開始.</param>
public HeaderCell(int startColIndex, int endColIndex,int startDeepIndex,int endDeepIndex,int deepCount)
{
this.startColIndex = startColIndex;
this.endColIndex = endColIndex;
this.deepCount = deepCount;
this.startDeepIndex = startDeepIndex;
this.endDeepIndex = endDeepIndex;
}
public int StartColIndex
{
get
{
return this.startColIndex;
}
set
{
this.startColIndex = value;
}
}
public int EndColIndex
{
get
{
return this.endColIndex;
}
set
{
this.endColIndex = value;
}
}
public int DeepCount
{
get
{
return this.deepCount;
}
set
{
this.deepCount = value;
}
}
public int StartDeepIndex
{
get
{
return this.startDeepIndex;
}
set
{
this.startDeepIndex = value;
}
}
public int EndDeepIndex
{
get
{
return this.endDeepIndex;
}
set
{
this.endDeepIndex = value;
}
}
}
{
private int startColIndex;
private int endColIndex;
private int deepCount;
private int startDeepIndex;
private int endDeepIndex;
/// <summary>
///
/// </summary>
/// <param name="startColIndex"></param>
/// <param name="endColIndex"></param>
/// <param name="deepCount"></param>
/// <param name="deepIndex">從下往上數,序號從1開始.</param>
public HeaderCell(int startColIndex, int endColIndex,int startDeepIndex,int endDeepIndex,int deepCount)
{
this.startColIndex = startColIndex;
this.endColIndex = endColIndex;
this.deepCount = deepCount;
this.startDeepIndex = startDeepIndex;
this.endDeepIndex = endDeepIndex;
}
public int StartColIndex
{
get
{
return this.startColIndex;
}
set
{
this.startColIndex = value;
}
}
public int EndColIndex
{
get
{
return this.endColIndex;
}
set
{
this.endColIndex = value;
}
}
public int DeepCount
{
get
{
return this.deepCount;
}
set
{
this.deepCount = value;
}
}
public int StartDeepIndex
{
get
{
return this.startDeepIndex;
}
set
{
this.startDeepIndex = value;
}
}
public int EndDeepIndex
{
get
{
return this.endDeepIndex;
}
set
{
this.endDeepIndex = value;
}
}
}
再做一個函數用來重畫表頭,在這里我還做了一個重載:
private void SetColTitle(DataGridView dgv, HeaderCell topColumn, PaintEventArgs e, string title)
{
SetColTitle(dgv, topColumn, e, title, dgv.ColumnHeadersDefaultCellStyle.BackColor, dgv.ColumnHeadersDefaultCellStyle.ForeColor);
}
private void SetColTitle(DataGridView dgv, HeaderCell topColumn, PaintEventArgs e, string title,Color backColor,Color foreColor)
{
int x = 2;
int width = 0;
int y = 4;
int height = (dgv.ColumnHeadersHeight-4)*(topColumn.EndDeepIndex-topColumn.StartDeepIndex+1)/topColumn.DeepCount;
if (dgv.RowHeadersVisible)
{
x += dgv.RowHeadersWidth;
}
for (int i = 0; i < topColumn.StartColIndex; i++)
{
x += dgv.Columns[i].Width;
}
for (int i = topColumn.StartColIndex; i <= topColumn.EndColIndex; i++)
{
width += dgv.Columns[i].Width;
}
width -= 2;
y += (dgv.ColumnHeadersHeight-4) * (topColumn.DeepCount - topColumn.EndDeepIndex) / topColumn.DeepCount;
Rectangle rec = new Rectangle(x, y, width, height);
Color bkClr = dgv.ColumnHeadersDefaultCellStyle.BackColor;
if (backColor != null)
{
bkClr = backColor;
}
e.Graphics.FillRectangle(new SolidBrush(bkClr), rec);
if (topColumn.StartDeepIndex != 1)
{
ControlPaint.DrawBorder(e.Graphics, new Rectangle(x - 1, y + height-2, width + 2, 2), SystemColors.ControlLight, ButtonBorderStyle.Inset);
}
StringFormat format1 = new StringFormat();
format1.Trimming = StringTrimming.EllipsisWord;
format1.Alignment = StringAlignment.Center;
format1.LineAlignment = StringAlignment.Center;
Color foClr = dgv.ColumnHeadersDefaultCellStyle.ForeColor;
if (foreColor != null)
{
foClr = foreColor;
}
e.Graphics.DrawString(title, dgv.ColumnHeadersDefaultCellStyle.Font, new SolidBrush(foClr), rec, format1);
}
{
SetColTitle(dgv, topColumn, e, title, dgv.ColumnHeadersDefaultCellStyle.BackColor, dgv.ColumnHeadersDefaultCellStyle.ForeColor);
}
private void SetColTitle(DataGridView dgv, HeaderCell topColumn, PaintEventArgs e, string title,Color backColor,Color foreColor)
{
int x = 2;
int width = 0;
int y = 4;
int height = (dgv.ColumnHeadersHeight-4)*(topColumn.EndDeepIndex-topColumn.StartDeepIndex+1)/topColumn.DeepCount;
if (dgv.RowHeadersVisible)
{
x += dgv.RowHeadersWidth;
}
for (int i = 0; i < topColumn.StartColIndex; i++)
{
x += dgv.Columns[i].Width;
}
for (int i = topColumn.StartColIndex; i <= topColumn.EndColIndex; i++)
{
width += dgv.Columns[i].Width;
}
width -= 2;
y += (dgv.ColumnHeadersHeight-4) * (topColumn.DeepCount - topColumn.EndDeepIndex) / topColumn.DeepCount;
Rectangle rec = new Rectangle(x, y, width, height);
Color bkClr = dgv.ColumnHeadersDefaultCellStyle.BackColor;
if (backColor != null)
{
bkClr = backColor;
}
e.Graphics.FillRectangle(new SolidBrush(bkClr), rec);
if (topColumn.StartDeepIndex != 1)
{
ControlPaint.DrawBorder(e.Graphics, new Rectangle(x - 1, y + height-2, width + 2, 2), SystemColors.ControlLight, ButtonBorderStyle.Inset);
}
StringFormat format1 = new StringFormat();
format1.Trimming = StringTrimming.EllipsisWord;
format1.Alignment = StringAlignment.Center;
format1.LineAlignment = StringAlignment.Center;
Color foClr = dgv.ColumnHeadersDefaultCellStyle.ForeColor;
if (foreColor != null)
{
foClr = foreColor;
}
e.Graphics.DrawString(title, dgv.ColumnHeadersDefaultCellStyle.Font, new SolidBrush(foClr), rec, format1);
}
3.添加DataGridView的Paint事件,並在事件中調用SetColTitle函數繪製表頭
this.dataGridView1.Paint += new System.Windows.Forms.PaintEventHandler(this.dataGridView1_Paint);
private void dataGridView1_Paint(object sender, PaintEventArgs e)
{
HeaderCell h = new HeaderCell(1, 3, 3,3, 3);
SetColTitle((DataGridView)sender, h, e, "第一列", Color.LightGreen, Color.Red);
HeaderCell hc=new HeaderCell(1,2,2,2,3);
SetColTitle((DataGridView)sender, hc, e, "第一列",Color.LightGreen,Color.Red);
HeaderCell hc1 = new HeaderCell(1, 1, 1,1, 3);
SetColTitle((DataGridView)sender, hc1, e, "分列1", Color.Purple, Color.Red);
HeaderCell hc2 = new HeaderCell(2, 2, 1, 1,3);
SetColTitle((DataGridView)sender, hc2, e, "分列2", Color.Pink, Color.Red);
HeaderCell hc3 = new HeaderCell(3, 3, 1, 2,3);
SetColTitle((DataGridView)sender, hc3, e, "分列", Color.LightGreen, Color.Red);
}
private void dataGridView1_Paint(object sender, PaintEventArgs e)
{
HeaderCell h = new HeaderCell(1, 3, 3,3, 3);
SetColTitle((DataGridView)sender, h, e, "第一列", Color.LightGreen, Color.Red);
HeaderCell hc=new HeaderCell(1,2,2,2,3);
SetColTitle((DataGridView)sender, hc, e, "第一列",Color.LightGreen,Color.Red);
HeaderCell hc1 = new HeaderCell(1, 1, 1,1, 3);
SetColTitle((DataGridView)sender, hc1, e, "分列1", Color.Purple, Color.Red);
HeaderCell hc2 = new HeaderCell(2, 2, 1, 1,3);
SetColTitle((DataGridView)sender, hc2, e, "分列2", Color.Pink, Color.Red);
HeaderCell hc3 = new HeaderCell(3, 3, 1, 2,3);
SetColTitle((DataGridView)sender, hc3, e, "分列", Color.LightGreen, Color.Red);
}
4.說明:這個方法做出來的效果現在還是不能用,當調整表頭寬度時和出滾動條時刷新有問題.以後再試研究看.如果還是不行,那就用CellPainting事件做做看吧,再不行,就用Tree加DataGridView做成控件的形式試試.