重写GridView
重写GridView
效果
使用中遇到的问题:
1. 不便于使用CSS控制样式,特别是border-collapse: separate属性总是在border=0时自动出现。
2. 分页样式过于单调,喜欢aspnetPager的样式,也就是用一个DropDownList。
3. 当DataSource为null的时候,虽然可以显示EmptyDataText或EmptyDataTemplate,但不显示Header。
解决方法:
1. 使用WebControlAdapter重写GridView的输出。
2. 重写CreateChildControls方法,生成自定义的PagerRow。
3. 重写CreateChildControls方法,即使没有数据,也生成Header或Footer;同时使用WebControlAdapter重写输出。
细节:
1. 如何使用WebControlAdapter重写GridView的输出。
这个问题大家可以参考微软的CssAdapters,我稍微修改了一下,添加了对AutoGenerateColumns==true的情况的考虑。详细就不多说了,具体见Demo的代码。
生成的Html代码好多了。
<table cellspacing="0" summary="">
<thead>
<tr class="headRow">
<th class="listNo" scope="col">No.</th>
<th class="name" scope="col">名称</th>
<th class="desc" scope="col">描述</th>
<th class="listOp" scope="col"> </th>
</tr>
</thead>
<tbody>
<tr class="row">
<td class="listNo">1</td>
<td class="name">角色0</td>
<td class="desc">角色0备注</td>
<td class="listOp"><a id="GvRole_ctl02_HLEdit" title="编辑" class="opEdit" href="#"><img title="编辑" src="App_Themes/Default/opEdit.gif" style="border-width:0px;" /></a><input type="image" name="GvRole$ctl02$IBtnDelete" id="GvRole_ctl02_IBtnDelete" title="删除" class="opDel" src="App_Themes/Default/opDel.gif" alt="删除" style="border-width:0px;" /></td>
</tr>
<tr class="alternatingRow">
<td class="listNo">2</td>
<td class="name">角色1</td>
<td class="desc">角色1备注</td>
<td class="listOp"><a id="GvRole_ctl03_HLEdit" title="编辑" class="opEdit" href="#"><img title="编辑" src="App_Themes/Default/opEdit.gif" style="border-width:0px;" /></a><input type="image" name="GvRole$ctl03$IBtnDelete" id="GvRole_ctl03_IBtnDelete" title="删除" class="opDel" src="App_Themes/Default/opDel.gif" alt="删除" style="border-width:0px;" /></td>
</tr>
............................
<tr class="alternatingRow">
<td class="listNo">10</td>
<td class="name">角色9</td>
<td class="desc">角色9备注</td>
<td class="listOp"><a id="GvRole_ctl11_HLEdit" title="编辑" class="opEdit" href="#"><img title="编辑" src="App_Themes/Default/opEdit.gif" style="border-width:0px;" /></a><input type="image" name="GvRole$ctl11$IBtnDelete" id="GvRole_ctl11_IBtnDelete" title="删除" class="opDel" src="App_Themes/Default/opDel.gif" alt="删除" style="border-width:0px;" /></td>
</tr>
</tbody>
</table>
<div class="pagination bottom"><div class="hint">
共30个记录 第1 / 3页 </div><div class="op">
<a href="javascript:__doPostBack('GvRole','Page$Next')">下一页</a>
<a href="javascript:__doPostBack('GvRole','Page$Last')">尾页</a>
<span>跳转到:</span>
<select name="GvRole$ctl13$PageList" onchange="javascript:setTimeout('__doPostBack(\'GvRole$ctl13$PageList\',\'\')', 0)" id="GvRole_ctl13_PageList">
<option selected="selected" value="0">第1页</option>
<option value="1">第2页</option>
<option value="2">第3页</option></select></div>
</div>
2. 如何实现自定义分页
在CreateChildControls方法中,清除PagerRow中的Controls,添加自己需要的Controls。别的不多说,关键是DropDownList的事件如何处理。我的办法是利用反射,调用GridView的HandleEvent方法处理翻页事件。(虽然不太好,只怪HandleEvent是private的)
private void PageList_Click(Object sender, EventArgs e)
{
int i = int.Parse(((DropDownList)sender).SelectedValue);
GridViewCommandEventArgs gce = new GridViewCommandEventArgs(sender, new CommandEventArgs("Page", (i+1).ToString()));
MethodInfo method = typeof(System.Web.UI.WebControls.GridView).GetMethod("HandleEvent", BindingFlags.NonPublic | BindingFlags.Instance);
if (method != null)
{
object[] args = new object[3];
args[0] = gce;
args[1] = false;
args[2] = String.Empty;
method.Invoke(this, args);
}
}
3. 如何在DataSource为null显示Header或Footer
这个稍微复杂一点,但也不困难。在CreateChildControls方法中,不论是否有数据,初始化HeaderRow或FooterRow,然后用反射,设置其中的Cell,最后添加到Table中。
DataControlField[] fieldArray = this.Fields;
if (fieldArray != null && fieldArray.Length > 0)
{
if (this.ShowHeader && (this.HeaderRow == null || addHeaderAndFooter) && this.ShowHeaderAlways)
{
GridViewRow headerRow = null;
GridViewRowEventArgs args;
if (this.HeaderRow == null)
{
headerRow = this.CreateRow(-1, -1, DataControlRowType.Header, DataControlRowState.Normal);
this.InitializeRow(headerRow, fieldArray);
FieldInfo field = typeof(System.Web.UI.WebControls.GridView).GetField("_headerRow", BindingFlags.NonPublic | BindingFlags.Instance);
if (field != null)
{
field.SetValue(this, headerRow);
}
((Table)this.Controls[0]).Rows.Add(headerRow);
this.addHeaderAndFooter = true;
}
else
{
headerRow = this.HeaderRow;
}
args = new GridViewRowEventArgs(headerRow);
this.OnRowCreated(args);
if (dataBinding)
{
headerRow.DataBind();
this.OnRowDataBound(args);
headerRow.DataItem = null;
}
}
}
其它…
posted on 2006-11-29 03:00 sherwinzhu 阅读(5596) 评论(20) 编辑 收藏 举报