日期:2014-05-17 浏览次数:21728 次
/// <summary>
/// 支持双行表头的的DataGridView
///
/// 用法示例:
/// dg.AddSpanHeader(4, 4, "主标题 ");
/// 则将第4列开始的4列设为双行表头,主标题为“主标题”,子标题为原来的 Value 值
///
/// phommy@hotmail.com
/// </summary>
public partial class DataGridViewEx1 : DataGridView
{
public DataGridViewEx1()
{
InitializeComponent();
}
protected override void OnPaint(PaintEventArgs pe)
{
// TODO: 在此处添加自定义绘制代码
// 调用基类 OnPaint
base.OnPaint(pe);
}
private struct SpanInfo //表头信息
{
public SpanInfo(string Text, int Position, int Left, int Right)
{
this.Text = Text;
this.Position = Position;
this.Left = Left;
this.Right = Right;
}
public string Text; //列主标题
public int Position; //位置,1:左,2中,3右
public int Left; //对应左行
public int Right; //对应右行
}
private Dictionary <int, SpanInfo> SpanRows = new Dictionary <int, SpanInfo> ();//需要2维表头的列
public void AddSpanHeader(int ColIndex, int ColCount, string Text)
{
if (ColCount < 2)
throw new Exception( "行宽应大于等于2,合并1列无意义。 ");
//检查范围
for (int i = 0; i < ColCount; i++)
{
if (SpanRows.ContainsKey(ColIndex + i))
throw new Exception( "单元格范围重叠! ");
}
//将这些列加入列表
int Right = ColIndex + ColCount - 1; //同一大标题下的最后一列的索引
SpanRows[ColIndex] = new SpanInfo(Text, 1, ColIndex, Right); //添加标题下的最左列
SpanRows[Right] = new SpanInfo(Text, 3, ColIndex, Right); //添加该标题下的最右列
for (int i = ColIndex + 1; i < Right; i++) //中间的列
{
SpanRows[i] = new SpanInfo(Text, 2, ColIndex, Right);
}
}
public void ClearSpanInfo()
{
SpanRows.Clear();
//ReDrawHead();
}
private void DataGridViewEx_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
{
if (e.RowIndex == -1)
{
if (SpanRows.ContainsKey(e.ColumnIndex)) //被合并的列
{
//画边框
Graphics g = e.Graphics;
e.Paint(e.CellBounds, DataGridViewPaintParts.Background | DataGridViewP