我做的项目当要实现DATAGRIDVIEW的多维表头,在网上看到有人重写的DATAGRIDVIEW控件HeaderUnitView.cs,但是容易花掉,和出错,考虑到代码的安全性不知道.NET控件达人人有没有什么好的方法以共参考以下呢HELP 达人们````
解决方案 »
- 窗体间的信息获取
- 开源代码生成软件Tstring.Core.Builder
- 关于公共数据配置字符串的问题
- 这的什么原因呀?
- 为什么设置的断点无效?
- 在C#中如何对Excel单元格设置背景色以及对Range设边框
- 请教一个用ASP.NET(C#)从Oracle读取BLOB字段的问题,急!!!!!!!!!!!
- 如何计算用DrawString绘制的字符串象素长度和高度???
- 请教DATASET导出导入XML文件速度快,还是导入导出EXCEL文件效率快?
- 大家好:圣诞快乐,请问在C#中别人写一个最简单的控件(包括如何安装),我想改成。还可以加分(要多少可以说(10-100))
- " &= "运算符的意思
- 跨省添加记录,ADO与ADO.NET那一个速度更快
gridResult.HeaderRow.Cells.Clear();
//新建一个单元格
TableCell cell = new TableCell();
//注意下面的HTML的写法
cell.Text = "标题1</td><td colspan='2'>标题2</td><td rowspan='2'>标题3</td></tr><tr><td>标题11</td><td>标题21</td><td>标题22";
gridResult.HeaderRow.Cells.Add(cell);这样运行后会在页面上生成一个类似这样的表格:标题1 标题2 标题3
标题11 标题21 标题22
1 2 3 4
但是这个表头是相对比较简单的,如果再复杂一些,比如有几十个甚至上百个列的情况,并且需要有比较复杂的样式设置,这种直接拼合HTML字符串的方法可能有点力不从心了,一个比较简单的方法是,在页面上定义画一个Table,包含表头需要的所有列及样式,然后在代码中实时取得这个Table的Row的HTML源代码(关于在代码中取得Table的HTML代码,可以参考 asp.net导出文件,支持中文文件名 和 在从GridView导出时Excel报错),再用上面的方法加入到GridView的表头中就可以了,需要注意的是自定义的HTML与GridView生成的HTML的整合,这个可以尽量发挥自己的想象了,没有最好只有更好!
//清空表头行的原有的单元格
GridView1.HeaderRow.Cells.Clear();
//新建一个单元格
TableCell cell = new TableCell();
cell.Text = "标题1</td><td >标题2</td><td>标题3</td>
//添加新的表头
GridView1.HeaderRow.Cells.Add(cell);
这样就可以生成 标题1 标题2 标题3 作为表头了
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="false" BorderWidth="1" Width="100%" BorderColor="#93BEE2" BorderStyle="Solid" CellPadding="0" Font-Size="12px" ForeColor="Black" PageIndex="0" AllowPaging=true PageSize="15" OnPageIndexChanging="GridView1_PageIndexChanging" OnRowCreated="GridView1_RowCreated">
<Columns>
<asp:BoundField HeaderText="全宗号" DataField="WholeID" />
<asp:BoundField HeaderText="全宗名称" DataField="WholeName" />
<asp:BoundField HeaderText="目录启止号" DataField="MenuStartEndID" />
<asp:BoundField HeaderText="启止年代" DataField="StartEndDatetime" />
<asp:BoundField HeaderText="合计档案" DataField="ThisTotal" />
<asp:BoundField HeaderText="永久档案" DataField="ThisForever" />
<asp:BoundField HeaderText="长期档案" DataField="ThisLong" />
<asp:BoundField HeaderText="短期档案" DataField="ThisShort" />
<asp:BoundField HeaderText="存放位置" DataField="SavePlace" />
<%--<asp:BoundField HeaderText="档案信息存储数字化情况" DataField="AsNumber" />--%>
<asp:TemplateField HeaderText="档案信息存储数字化情况">
<ItemTemplate>
<%# (DataBinder.Eval(Container.DataItem, "AsNumber").ToString().Length > 10) ? DataBinder.Eval(Container.DataItem, "AsNumber").ToString().Substring(0, 10) + "..." : DataBinder.Eval(Container.DataItem, "AsNumber").ToString()%>
</ItemTemplate>
</asp:TemplateField>
<%--<asp:BoundField HeaderText="备注" DataField="Re" />--%>
<asp:TemplateField HeaderText="备注">
<ItemTemplate>
<%# (DataBinder.Eval(Container.DataItem, "Re").ToString().Length > 10) ? DataBinder.Eval(Container.DataItem, "Re").ToString().Substring(0, 10) + "..." : DataBinder.Eval(Container.DataItem, "Re").ToString()%>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="操作">
<ItemTemplate>
<div style="text-align:center">
<a href="CartularyWholeStatisticEdit.aspx?CartularyWholeStatisticID=<%# DataBinder.Eval(Container, "DataItem.CartularyWholeStatisticID")%>&PageIndex=<%=PageIndex%>">编辑</a> <a onclick="return delconfirm()" href="CartularyWholeStatisticDele.aspx?CartularyWholeStatisticID=<%# DataBinder.Eval(Container, "DataItem.CartularyWholeStatisticID")%>&PageIndex=<%=PageIndex%>">删除</a>
</div>
</ItemTemplate>
<ItemStyle Width="100px" />
</asp:TemplateField>
</Columns>
<HeaderStyle BackColor="#337FB2" Font-Bold="False" Font-Size="12px" ForeColor="White" Height="22px" />
<RowStyle Height="22px" Font-Size="12px" HorizontalAlign=Center />
<AlternatingRowStyle Height="22px" BackColor="#E8F4FF" />
<PagerStyle HorizontalAlign="Right" />
</asp:GridView>
////////////////////////////////////
DataGridView表头合并
/// <summary>
/// 合并表头
/// </summary>
public class HeaderGridView
{
#region 合并Header 创建表头区域的使用到的位置和大小属性 int cTop = 0;//被合并表头区域的顶部Y坐标
int cLeft = 0;//被合并表头区域的左边X坐标
int cWidth = 0; // 被合并表头区域的宽
int cHeight = 0;//高 #endregion
// private HeaderGridView() { } private HeaderGridView() { }
#region single mode private static object m_lock_object = new object();
private static HeaderGridView m_header;
public static Hashtable hs = new Hashtable();
public static HeaderGridView GetSingle()
{
if (m_header == null)
{
lock (m_lock_object)
{
if (m_header == null)
{
m_header = new HeaderGridView(); }
}
}
return m_header;
} #endregion /// <summary>
/// 合并表头,用在dataGridView的CellPainting事件中。
/// </summary>
/// <param name="sender">需要重绘的dataGridview</param>
/// <param name="e">CellPainting中的参数</param>
///<param name="colName">列的集合(列必须是连续的,第一列放在最前面)</param>
/// <param name="headerText">列合并后显示的文本</param>
public void MergeHeader(object sender, DataGridViewCellPaintingEventArgs e, List<string> colNameCollection, string headerText)
{
if (e.RowIndex == -1 && e.ColumnIndex != -1)
{
DataGridView dataGridView1 = sender as DataGridView;
string colName = dataGridView1.Columns[e.ColumnIndex].Name; //0.扩展表头高度为当前的2倍
if (!hs.Contains(dataGridView1.Name))
{
hs.Add(dataGridView1.Name, "0");
dataGridView1.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.EnableResizing;
dataGridView1.ColumnHeadersHeight = e.CellBounds.Height * 2;
} if (colNameCollection.Contains(colName))
{
#region 重绘列头
//1.计算colLen个列的区域
if (colNameCollection.IndexOf(colName) == 0)
{
cTop = e.CellBounds.Top;
cLeft = e.CellBounds.Left; cWidth = e.CellBounds.Width;
cHeight = e.CellBounds.Height / 2;
//求总的合并列的宽度
foreach (string colNameItem in colNameCollection)
{
if (colNameItem.Equals(colName))
{//除去自己一个,加了之后colLen-1个列的宽
continue;
}
cWidth += dataGridView1.Columns[colNameItem].Width;
}
}
if (colNameCollection.IndexOf(colName) == 0)
{
Rectangle cArea = new Rectangle(cLeft, cTop, cWidth, cHeight);
//2.把区域设置为背景色,没有列的分线及任何文字。
using (Brush backColorBrush = new SolidBrush(e.CellStyle.BackColor))
{
e.Graphics.FillRectangle(backColorBrush, cArea); }
}
{
//3.绘制新列头的边框
using (Pen gridPen = new Pen(dataGridView1.GridColor))
{
//3.1 上部边框
e.Graphics.DrawLine(gridPen, cLeft, cTop, cLeft + cWidth, cTop);
using (Pen hilightPen = new Pen(Color.WhiteSmoke))
{
//3.2 顶部高光
e.Graphics.DrawLine(hilightPen, cLeft, cTop + 1, cLeft + cWidth, cTop + 1);
//3.3 左部反光线
e.Graphics.DrawLine(hilightPen, cLeft, cTop + 3, cLeft, cTop + cHeight - 2);
}
//3.4 下部边框
e.Graphics.DrawLine(gridPen, cLeft, cTop + cHeight - 1, cLeft + cWidth, cTop + cHeight - 1);
//3.5 右部边框
e.Graphics.DrawLine(gridPen, cLeft + cWidth - 1, cTop, cLeft + cWidth - 1, cTop + cHeight);//(cTop+cHeight)/2);
}
} //4.Header 写文本
if (colNameCollection.IndexOf(colName) == 0)
{//不是第一列则不写文字。 int wHeadStr = (int)(headerText.Length * e.CellStyle.Font.SizeInPoints);
int wHeadCell = cWidth;
int pHeadLeft = (wHeadCell - wHeadStr) / 2 - 6;
using (Brush foreBrush = new SolidBrush(e.CellStyle.ForeColor))
{
e.Graphics.DrawString(headerText, e.CellStyle.Font, foreBrush, new PointF(cLeft + pHeadLeft, cTop + 3));
}
}
////5 绘制子列背景
int FatherColHeight = e.CellBounds.Height / 2;//上面一行的高度
using (Brush backColorBrush = new SolidBrush(e.CellStyle.BackColor))
{
e.Graphics.FillRectangle(backColorBrush, new Rectangle(e.CellBounds.X, e.CellBounds.Y + FatherColHeight, e.CellBounds.Width - 1, e.CellBounds.Height / 2 - 1));
}
////5.1绘制子列的边框 using (Pen gridPen = new Pen(dataGridView1.GridColor))
{
using (Pen hilightPen = new Pen(Color.WhiteSmoke))
{
//5.2 左部反光线
e.Graphics.DrawLine(hilightPen, cLeft, cTop + 3 + FatherColHeight, cLeft, cTop + cHeight - 2 + FatherColHeight);
}
//5.3 下部边框
e.Graphics.DrawLine(gridPen, cLeft, cTop + cHeight - 1 + FatherColHeight, cLeft + cWidth, cTop + cHeight - 1 + FatherColHeight); //5.4 右部边框
e.Graphics.DrawLine(gridPen, e.CellBounds.X + e.CellBounds.Width - 1, e.CellBounds.Top + FatherColHeight, e.CellBounds.X + e.CellBounds.Width - 1, e.CellBounds.Top + e.CellBounds.Height + FatherColHeight);//(cTop+cHeight)/2); }
//5.5 写子列的文本
int wStr = (int)(dataGridView1.Columns[e.ColumnIndex].HeaderText.Length * e.CellStyle.Font.SizeInPoints);
int wCell = e.CellBounds.Width;
int pLeft = (wCell - wStr) / 2;//相对CELL左边框的左坐标 using (Brush foreBrush = new SolidBrush(e.CellStyle.ForeColor))
{
e.Graphics.DrawString(dataGridView1.Columns[e.ColumnIndex].HeaderText, e.CellStyle.Font, foreBrush, new PointF(e.CellBounds.X + pLeft, cTop + 3 + FatherColHeight));
} #endregion
e.Handled = true; //系统继续处理
}
}
} /// <summary>
/// 扩展表头高度为当前的2倍
/// </summary>
/// <param name="sender"></param>
public void HeightHeader(object sender, DataGridViewCellPaintingEventArgs e)
{
DataGridView dataGridView1 = sender as DataGridView;
if (!hs.Contains(dataGridView1.Name))
{
hs.Add(dataGridView1.Name, "0");
dataGridView1.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.EnableResizing;
dataGridView1.ColumnHeadersHeight = e.CellBounds.Height * 2;
}
}
}
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;4,效果图
至于表尾合计,也做出了原型。二维表头+表尾合计,基本上满足需求了。
这样就把GridView转换成了双层表头,你可以点band进行表头的设定,次表头对应的列
我也不知道我理解的是不是你所要的东西,暂且回个帖,希望对你有帮助
http://www.cnblogs.com/hehuaflower/archive/2009/02/28/1400188.html
http://topic.csdn.net/u/20090318/00/f271b9ee-7427-4bf6-89d8-ccaf00de235f.html
http://topic.csdn.net/u/20090318/00/e5137518-f2b5-4d81-8d4f-3acbbb87e681.html
http://topic.csdn.net/u/20090309/16/be37aff1-dadf-4a80-976a-49e0971af6ba.html
三个问题的分全给你 一共550分!!!!!!!!!!