admin - 2008-6-23 0:26:00
Introduction
你需要控制gridview的列宽,尤其是当gridview的宽度是相对与容器(例如:width= “100 %”)并且列的宽度始终未GridView分配给他们的所有的宽度?所有你想要的是每个列拥有足够的宽度,以显示其内容并且余下的宽度可以分配给最后一列,不过这样没用,不是吗? 你曾经尝试在一个gridview的rowstyle或headerstyle里使用Wrap= “False”然后为它在所有的浏览器上没有工作而感到惊讶?这篇文章是我采取解决这两个问题的,并且它可以同时工作与IE和FF
Background
我的解决方案依赖于javascript和DOM,我使用元素,注入到现在的HTML中.代码并不复杂,你不须害怕这些恐吓条款.您大概需要知道一点JavaScript和DOM(文档对象模型)实际上是指什么意思.如果你发现你缺少这些知识,花几分钟GOOGLE下就能帮到你
Using the code
这2部分对于解决方案来说,属于aspx页面的JavaScript,属于后台页面注册调用这些函数的代码
让我们从Javascript函数开始:
function formatGrid(el)
{
el = document.getElementById(el);
var numOfCols = el.getElementsByTagName("TR")[1].getElementsByTagName("TD").length;
var colGrp = document.createElement("colgroup");
var col = document.createElement("col");
col.setAttribute("span", numOfCols-1);
col.setAttribute("width", "1");
col.setAttribute("white-space", "nowrap");
col.setAttribute("padding-left", "2");
col.setAttribute("padding-right", "2");
col.setAttribute("border-width", "2");
colGrp.appendChild(col);
el.insertBefore(colGrp, el.firstChild);
}
formatGrid在我们的情况里通常会在gridview的document里接收每个元素的ID.这个函数做这些是为了格式化GridView以便每个列获得足够的宽度以显示内容,并让最后一列得到多余的宽度.记住我们通常在这里处理一个有100%宽度的GridView.为了让代码更易懂,我会指出以下几点:
1.我们从GridView numOfCols得到列数,然后numOfCols-1
2.ColGroup元素为分组列负责并且分配他们的公共属性
3.Col元素是ColGroup元素的子元素
4.在我们的方案里我们需要约束所有的列宽除了最后一列,span属性指出哪些列受影响
5.唯一的必要属性是span和width属性,其他都是可选的。
以下函数解决包装问题的一部分:
function addNoWrapSpan(el, noWrap){
var span = document.createElement("span");
while(el.childNodes.length > 0)
{
var child = el.firstChild;
el.removeChild(child);
span.appendChild(child);
}
if(noWrap)
span.style.whiteSpace = "nowrap";
else
span.style.whiteSpace = "inherit";
el.appendChild(span);
}
function setNoWrap(el, noWrapTH, noWrapTD){
el = document.getElementById(el);
if(noWrapTH)
{
var allTHs = el.getElementsByTagName("TH");
for(var i = 0; i < allTHs.length; i++)
{
addNoWrapSpan(allTHs, noWrapTH);
}
}
if(noWrapTD)
{
var allTDs = el.getElementsByTagName("TD");
for(var i = 0; i < allTDs.length; i++)
{
addNoWrapSpan(allTDs, noWrapTD);
}
}
}
第一个addNoWrapSpan函数移动所有提供元素e1内部的元素到一个动态生成适合样式的span元素依赖取决于noWrap是true或者false.这个样式如下:
span.style.whiteSpace = "nowrap";
如果noWrap是true,如上,如果是false那么样式如下:
span.style.whiteSpace = "inherit";
setNoWrap接收3个参数:e1 我们配置哪个元素,noWrapTH 告诉我们是否或不容许包装TH's子元素,noWrapTD指示是否或不容许元素e1内的包装TD,你可能注意到,setNoWrap 必须调用addNoWrapSpan
所附的示例项目包括一个示例GridView:
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" Width="100%"
CssClass="GridClass">
<Columns>
<asp:BoundField DataField="FirstName" HeaderText="First Name" />
<asp:BoundField DataField="LastName" HeaderText="Last Name" />
<asp:BoundField DataField="Age" HeaderText="Age" />
<asp:CommandField ShowSelectButton="True" />
</Columns>
</asp:GridView>
只是它显示的数据集在后台代码设置,并且同样也有CommandField ,其中有一个专责linkbutton 。下面是后台代码:
private DataTable BuildDataSource()
{
DataTable dt = new DataTable();
dt.Columns.Add("FirstName", typeof(string));
dt.Columns.Add("LastName", typeof(string));
dt.Columns.Add("Age", typeof(int));
DataRow dr;
dr = dt.NewRow();
dr["FirstName"] = "John";
dr["LastName"] = "Doe";
dr["Age"] = 23;
dt.Rows.Add(dr);
dr = dt.NewRow();
dr["FirstName"] = "Clark";
dr["LastName"] = "Kent";
dr["Age"] = 28;
dt.Rows.Add(dr);
return dt;
}
这是一个简单的为测试目而显示数据的方法,这是取代从数据库检索数据的方法
protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
string formatScript = "";
formatScript += string.Format("formatGrid('{0}');setNoWrap('{0}', false, true);", GridView1.ClientID);
ClientScript.RegisterStartupScript
(this.GetType(), "format", formatScript, true);
}
附件:
CodeProject-Dynamic-Column-Width_GridView.zip