接到上面的order, 将DataGrid改写成表头固定, 而要带scroll bar滚动记录. 看了felix兄的文章
Fixed Header Scrollable DataGrid control http://blog.joycode.com/felix/articles/32789.aspx
好像有点不太适合自己用. 他将Header截出来, 做成Div, 然后把原来的DataGrid Header盖住, 形成一种假象, 就像表头真的被固定了, 而且两者的位置好像对得不准, 新生成的Header有点左移(不知道是不是我机子的问题 ). 后来按照我跟上司的设想, 因为DataGrid最终输出的是一个Table, 所以将这个Table拆分为三部份, Header, Items, Pager. 然后在Items外面加一个Div, 用javascript控制Div是否出现Scroll bar.
BTW: 因为DataGrid我们是重新封装过的. 有部份代码只适合此Grid使用, 但万变不离其中. enjoy it . 
/// <summary> /// Author : Kenneth Lee /// Create Date : 2004-11-8 /// Description : override Render方法, 在网格输出时, 修改网站的样式. /// 将整个DataGrid划分为Headers, Items, Pager 三个表格, 利用Div的属性控制是否出现scroll bar. /// 并且确保客户端调整控件其它样式时, 其样式保持不变. /// </summary> /// <param name="writer"></param> protected override void Render(HtmlTextWriter writer) { //确定DataGrid处于何种状态, 是运行时还是设计时 //Control.Site属性是获取控件当前站点的信息 bool gridDesignMode = ((Site != null) && (Site.DesignMode));
//只有运行时输出以下内容 if (!gridDesignMode) { // 将HTML转换为StringBuilder StringWriter sw = new StringWriter();
HtmlTextWriter htw = new HtmlTextWriter(sw);
//保证每列的宽度 Style["TABLE-LAYOUT"] = "fixed";
// 输出到sw中. base.Render(htw);
StringBuilder sbRenderedTable = sw.GetStringBuilder();
htw.Close();
sw.Close();
string temp = sbRenderedTable.ToString();
if (sbRenderedTable.Length > 0) { if (this.HeaderText == string.Empty) { // 将DataGrid的ID替换为表头ID sbRenderedTable.Replace(ID,ID + "_Headers", 0, (temp.IndexOf(ID) + ID.Length)); // 为保持表头和表脚的高度, 将height属性去掉. sbRenderedTable.Remove(sbRenderedTable.ToString().ToLower().IndexOf("height:"), this.Height.ToString().Length+8); temp = sbRenderedTable.ToString(); //找出表头的长度. 以便分拆 int start = temp.ToLower().IndexOf(@"<");
int end = temp.ToLower().IndexOf(@">") + 1;
string strTableStyle = temp.Substring(start,end-start); //因为要将DataGrid划分为三个表格, 所以用一个大的DIV固定它们的宽度.并且保证scroll bar不出现. //要确保scroll bar不出, 用overflow-y:hidden就够了 if (this.Height.ToString() == string.Empty || this.Height.ToString() == "100%") { sbRenderedTable.Insert(0,@"<div id='" + this.ID + "_full' style='Align:center; WIDTH: 100%; overflow-y:hidden'>"); } else { sbRenderedTable.Insert(0,@"<div id='" + this.ID + "_full' style='Align:center; Width: 100%; overflow-y:hidden;Height:" + this.Height.ToString() + @"'>"); } temp = sbRenderedTable.ToString();
strTableStyle = strTableStyle.Replace(this.ID+"_Headers", ID + "_Items");
//将表头与内容分拆开. 并为内容加入一个DIV以显示scroll bar sbRenderedTable.Insert((temp.ToLower()).IndexOf(@"</tr>") + 5,@"</table>"+ @"<div id='" + this.ID + @"_div' style= 'WIDTH:100%;TOP:;LEFT:;POSITION:;Z-INDEX:;OVERFLOW-X: hidden;OVERFLOW-Y:auto'> " + strTableStyle);
string strTablePager = strTableStyle.Replace(this.ID + "_Items", this.ID + "_Pager");
int intHeightIndex = strTablePager.ToLower().IndexOf("height:");
if (intHeightIndex > 0) { strTablePager = strTablePager.Remove(intHeightIndex, this.Height.ToString().Length+8); }
//将内容与分页拆开. sbRenderedTable.Insert(sbRenderedTable.ToString().ToLower().IndexOf(@"<tr style"),@"</table></div>"+strTablePager);
//使用Javascript将表头的列与内容的列的宽度匹配. StringBuilder adjustStyleScript = new StringBuilder(); adjustStyleScript.Append(@"<script language=javascript>"); adjustStyleScript.Append(@"var headerTableRow = "); adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_Headers.rows[0];");
// 判断记录是否为0, 如果为0则无需匹配表头与内容的列宽 adjustStyleScript.Append(@" if ("); adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_Items.rows.length !=0) {"); adjustStyleScript.Append(@"var originalTableRow = "); adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_Items.rows[0];"); adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_Headers.rows[0].width = originalTableRow.offsetWidth;"); adjustStyleScript.Append(this.ID + @"_Headers.style.width = " + this.ID + @"_full.offsetWidth;"); adjustStyleScript.Append(this.ID + @"_Pager.style.width = " + this.ID + @"_full.offsetWidth;"); adjustStyleScript.Append(@"for (var i = 0; i < headerTableRow.cells.length; i++) {"); adjustStyleScript.Append(@"headerTableRow.cells[i].width = originalTableRow.cells[i].offsetWidth;}"); adjustStyleScript.Append(@"}"); adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_Items.style.left = "); adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_div.offsetLeft;"); adjustStyleScript.Append(@"var MinItemHeight = 100;");
//统计每页一共有多少条记录 adjustStyleScript.Append(@"var itemsRowsLength = "); adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_Items.rows.length;");
//计算Items表生成的实际高度. adjustStyleScript.Append(@"var itemsTotalHeight = "); adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_Items.rows[0].offsetHeight * itemsRowsLength;"); // 判断整个控件的高度是否比预设的高度要小. adjustStyleScript.Append(@"if ("); adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_full.offsetHeight < MinItemHeight) {");
// 判断实际高度是否比减去表头和表脚的高度要小. adjustStyleScript.Append(@"if (itemsTotalHeight < MinItemHeight - "); adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_Headers.offsetHeight - "); adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_Pager.offsetHeight) {"); // 将Items外面的Div高度设定与实际生成高度相同. adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_div.style.Height = itemsTotalHeight;"); adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_div.style.width = "); adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_full.offsetWidth;");
// 每行的高度等于实际高度的平均值 adjustStyleScript.Append(@"for (var i = 0; i<"); adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_Items.rows.length; i++) {"); adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_Items.rows[i].height = itemsTotalHeight / itemsRowsLength; }"); adjustStyleScript.Append(@" }else{"); adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_div.style.height = MinItemHeight - "); adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_Headers.offsetHeight - "); adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_Pager.offsetHeight;"); adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_div.style.width = "); adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_Items.offsetWidth + 17+ 'px';"); adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_full.style.height = "); adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_Headers.offsetHeight + MinItemHeight + "); adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_Pager.offsetHeight;"); adjustStyleScript.Append(@"}"); adjustStyleScript.Append(@"} else {");
// 当整个控件的高度比预设大, 计算去除表头和表脚后的高度. adjustStyleScript.Append(@"var itemsHeight = "); adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_full.offsetHeight - "); adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_Headers.offsetHeight - "); adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_Pager.offsetHeight;"); // 判断Items表格的高度是否比去除表头和表脚后的高度要小. adjustStyleScript.Append(@"if (itemsTotalHeight < itemsHeight) {"); adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_div.style.width = "); adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_full.offsetWidth;"); adjustStyleScript.Append(@"for (var i = 0; i<"); adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_Items.rows.length; i++) {"); adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_Items.rows[i].height = itemsTotalHeight / itemsRowsLength;"); adjustStyleScript.Append(@" }"); adjustStyleScript.Append(@" } else {"); // 判断是否需要滚动条 adjustStyleScript.Append(@"if ("); adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_Items.offsetHeight > itemsHeight) {"); adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_div.style.width = "); adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_Items.offsetWidth + 17+ 'px';"); adjustStyleScript.Append(@"} else {"); adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_Items.style.height = itemsHeight;"); adjustStyleScript.Append(@" }"); adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_div.style.height = itemsHeight;"); adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_div.style.width = "); adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_full.offsetWidth;"); adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_full.style.height = itemsHeight + "); adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_Headers.offsetHeight + "); adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_Pager.offsetHeight;"); adjustStyleScript.Append(@" } } ");
adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_div.top = "); adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_Headers.offsetTop + "); adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_Headers.offsetHeight;");
adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_Items.style.top = "); adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_div.offsetTop;");
adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_Headers.style.position = 'static';"); adjustStyleScript.Append(@"</script>");
Page.RegisterStartupScript("dummyKey" + this.ID, adjustStyleScript.ToString());
sbRenderedTable.Append(@"</div>"); writer.Write(sbRenderedTable.ToString()); } else { sbRenderedTable.Replace(ID,ID + "_Headers", 0, (temp.IndexOf(ID) + ID.Length));
//将高度去掉. sbRenderedTable.Remove(sbRenderedTable.ToString().ToLower().IndexOf("height:"), this.Height.ToString().Length+8); // 因为表头存在两行. 所以要分别截取,以统计两行的字符串数. int intHeaderLength = 0; StringBuilder sbNewTable = new StringBuilder(sbRenderedTable.ToString());
string strBackup; string strTableStyle; temp = sbRenderedTable.ToString();
int start = temp.ToLower().IndexOf(@"<");
int end = temp.ToLower().IndexOf(@">") + 1;
// 将表头格式保存到strBackup和strTableStyle中 // strBackup的作用是用于统计, <table>, 第一行, 第二行表头的字符串长度. // strTableStyle的作用是保存<table>的样式. strBackup = strTableStyle = temp.Substring(start,end-start);
intHeaderLength += strBackup.Length;
sbNewTable.Remove(start,end-start);
temp = sbNewTable.ToString();
start = temp.ToLower().IndexOf(@"<tr"); end = temp.ToLower().IndexOf(@"</tr>") + 5;
strBackup = temp.Substring(start,end-start);
intHeaderLength += strBackup.Length;
sbNewTable.Remove(start,end-start);
temp = sbNewTable.ToString();
start = temp.ToLower().IndexOf(@"<tr"); end = temp.ToLower().IndexOf(@"</tr>") + 5;
strBackup = temp.Substring(start,end-start);
intHeaderLength += strBackup.Length; strTableStyle = strTableStyle.Replace(this.ID+"_Headers", ID + "_Items");
sbRenderedTable.Insert(intHeaderLength+3,@"</table>"+ @"<div id='" + this.ID + @"_div' style= 'WIDTH:100%;TOP:;LEFT:;POSITION:;Z-INDEX:;OVERFLOW-X: hidden;OVERFLOW-Y:auto'> " + strTableStyle);
//因为要将DataGrid划分为三个表格, 所以用一个大的DIV固定它们的宽度.并且保证scroll bar不出现. //要确保scroll bar不出, 用overflow-y:hidden就够了 if (this.Height.ToString() == string.Empty || this.Height.ToString() == "100%") { sbRenderedTable.Insert(0,@"<div id='" + this.ID + "_full' style='Align:center; WIDTH: 100%; overflow-y:hidden'>"); } else { sbRenderedTable.Insert(0,@"<div id='" + this.ID + "_full' style='Align:center; Width: 100%; overflow-y:hidden;Height:" + this.Height.ToString() + @"'>"); }
string strTablePager = strTableStyle.Replace(this.ID+"_Items", this.ID+"_Pager"); sbRenderedTable.Insert(sbRenderedTable.ToString().ToLower().IndexOf(@"<tr style"),@"</table></div>"+strTablePager);
StringBuilder adjustStyleScript = new StringBuilder();
adjustStyleScript.Append(@"<script language=javascript>"); adjustStyleScript.Append(@"var headerTableRow = "); adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_Headers.rows[1];");
adjustStyleScript.Append(@" if ("); adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_Items.rows.length !=0) {"); adjustStyleScript.Append(@"var originalTableRow = "); adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_Items.rows[0];"); adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_Headers.rows[0].width = originalTableRow.offsetWidth;"); adjustStyleScript.Append(this.ID + @"_Headers.style.width = " + this.ID + @"_full.offsetWidth;"); adjustStyleScript.Append(this.ID + @"_Pager.style.width = " + this.ID + @"_full.offsetWidth;"); adjustStyleScript.Append(@"for (var i = 0; i < headerTableRow.cells.length; i++) {"); adjustStyleScript.Append(@"headerTableRow.cells[i].width = originalTableRow.cells[i].offsetWidth;}"); adjustStyleScript.Append(@"}"); adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_Items.style.left = "); adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_div.offsetLeft;"); adjustStyleScript.Append(@"var MinItemHeight = 120;");
//统计每页一共有多少条记录 adjustStyleScript.Append(@"var itemsRowsLength = "); adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_Items.rows.length;");
//计算Items表生成的实际高度. adjustStyleScript.Append(@"var itemsTotalHeight = "); adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_Items.rows[0].offsetHeight * itemsRowsLength;"); // 判断整个控件的高度是否比预设的高度要小. adjustStyleScript.Append(@"if ("); adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_full.offsetHeight < MinItemHeight) {");
// 判断实际高度是否比减去表头和表脚的高度要小. adjustStyleScript.Append(@"if (itemsTotalHeight < MinItemHeight - "); adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_Headers.offsetHeight - "); adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_Pager.offsetHeight) {"); // 将Items外面的Div高度设定与实际生成高度相同. adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_div.style.Height = itemsTotalHeight;"); adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_div.style.width = "); adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_full.offsetWidth;");
// 每行的高度等于实际高度的平均值 adjustStyleScript.Append(@"for (var i = 0; i<"); adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_Items.rows.length; i++) {"); adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_Items.rows[i].height = itemsTotalHeight / itemsRowsLength; }"); adjustStyleScript.Append(@" }else{"); adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_div.style.height = MinItemHeight - "); adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_Headers.offsetHeight - "); adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_Pager.offsetHeight;"); adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_div.style.width = "); adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_Items.offsetWidth + 17+ 'px';"); adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_full.style.height = "); adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_Headers.offsetHeight + MinItemHeight + "); adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_Pager.offsetHeight;"); adjustStyleScript.Append(@"}"); adjustStyleScript.Append(@"} else {");
// 当整个控件的高度比预设大, 计算去除表头和表脚后的高度. adjustStyleScript.Append(@"var itemsHeight = "); adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_full.offsetHeight - "); adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_Headers.offsetHeight - "); adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_Pager.offsetHeight;"); // 判断Items表格的高度是否比去除表头和表脚后的高度要小. adjustStyleScript.Append(@"if (itemsTotalHeight < itemsHeight) {"); adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_div.style.width = "); adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_full.offsetWidth;"); adjustStyleScript.Append(@"for (var i = 0; i<"); adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_Items.rows.length; i++) {"); adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_Items.rows[i].height = itemsTotalHeight / itemsRowsLength;"); adjustStyleScript.Append(@" }"); adjustStyleScript.Append(@" } else {"); // 判断是否需要滚动条 adjustStyleScript.Append(@"if ("); adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_Items.offsetHeight > itemsHeight) {"); adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_div.style.width = "); adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_Items.offsetWidth + 17+ 'px';"); adjustStyleScript.Append(@"} else {"); adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_Items.style.height = itemsHeight;"); adjustStyleScript.Append(@" }"); adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_div.style.height = itemsHeight;"); adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_div.style.width = "); adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_full.offsetWidth;"); adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_full.style.height = itemsHeight + "); adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_Headers.offsetHeight + "); adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_Pager.offsetHeight;"); adjustStyleScript.Append(@" } } ");
adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_div.top = "); adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_Headers.offsetTop + "); adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_Headers.offsetHeight;");
adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_Items.style.top = "); adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_div.offsetTop;");
adjustStyleScript.Append(this.ID); adjustStyleScript.Append(@"_Headers.style.position = 'static';"); adjustStyleScript.Append(@"</script>");
Page.RegisterStartupScript("dummyKey" + this.ID, adjustStyleScript.ToString());
sbRenderedTable.Append(@"</div>"); writer.Write(sbRenderedTable.ToString()); } } } else { // 不会执行此句, 只有在设计视图中出现DataGrid base.Render(writer); } } 
|