代码下载位置: ExtremeASPNET2008_03.exe (192 KB)
Browse the Code Online
在本专栏的结尾。您将掌握足够的信息来决定应该在您的 ASP.NET 工具箱中保留多少个数据绑定控件。
与大多数模板控件相似,ItemTemplate 将成为您工作的重点。您须要将绑定数据集中每一行不断反复的 HTML 内容放在 ItemTemplate 里。
<asp:ListView runat="server" ID="_simpleTableListView"
DataSourceID="_moviesDataSource">
<LayoutTemplate>
<table>
<thead>
<tr>
<th>ID</th>
<th>Title</th>
<th>Release Date</th>
</tr>
</thead>
<tbody>
<asp:PlaceHolder runat="server" ID="itemPlaceholder" />
</tbody>
</table>
</LayoutTemplate>
<ItemTemplate>
<tr>
<td><%# Eval("movie_id") %></td>
<td><%# Eval("title") %></td>
<td><%# Eval("release_date", "{0:d}") %></td>
</tr>
</ItemTemplate>
</asp:ListView>
比如,我能够使用server端表格行取代 PlaceHolder 控件编写 LayoutTemplate。实现相同的效果:
<LayoutTemplate>
<table>
<thead>
<tr>
<th>ID</th>
<th>Title</th>
<th>Release Date</th>
</tr>
</thead>
<tbody>
<tr runat="server" ID="itemPlaceholder" />
</tbody>
</table>
</LayoutTemplate>
并且。该控件并不呈现其自身的 HTML。而是用 ItemTemplate 的内容取代。因此假设控件除在层次结构中保留位置以外无不论什么其他目的。这是更合乎逻辑的选择。
<asp:ListView runat="server"
ID="_simpleTableListView"
DataSourceID="_moviesDataSource">
<LayoutTemplate>
<ul>
<asp:PlaceHolder runat="server"
ID="itemPlaceholder" />
</ul>
</LayoutTemplate>
<ItemTemplate>
<li><%# Eval("title") %>,
<%# Eval("release_date", "{0:d}") %> </li>
</ItemTemplate>
</asp:ListView>
一种常见的情形是开发者为特定页面手动预先设计,通常包括 HTML 和 CSS。採用传统的 GridView 呈现数据表的特定设计总是非常难保证正确,由于 GridView 类仅提供用于改动 HTML 结果的有限挂接集。
HTML
<div class="PrettyGrid">
<table cellpadding="0" cellspacing="0" summary="">
<thead>
<tr>
<th scope="col"><a href="http://.">ID</a></th>
<th scope="col"><a href="http://.">Title</a></th>
<th scope="col"><a href="http://.">Release date</a></th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Where the Wild Things Are</td>
<td>12/15/2008</td>
</tr>
<!-- ... -->
</tbody>
</table>
<div class="Pagination">
<span>1</span>
<a href="http://.">2</a>
<a href="http://.">3</a>
</div>
</div>
.PrettyGrid
{
width: 100%;
}
.PrettyGrid div.Pagination,
.PrettyGrid div.Pagination a,
.PrettyGrid div.Pagination span
{
color: #00FFFF;
background: #284775;
font-weight: normal;
padding: 2px;
}
.PrettyGrid table
{
border: solid 1px #CCCCCC;
width: 100%;
}
/*...*/
仅更新 HTML 或对应的 CSS 就能够非常easy地改动设计。
<asp:ListView ID="_moviesGrid" runat="server" DataKeyNames="movie_id"
DataSourceID="_moviesDataSource">
<LayoutTemplate>
<div class="PrettyGrid">
<table cellpadding="0" cellspacing="0" summary="">
<thead>
<tr>
<th scope="col"><a href="http://.">ID</a ></th>
<th scope="col"><a href="http://.">Title</a></th>
<th scope="col"><a href="http://.">Release date</a></th>
</tr>
</thead>
<tbody>
<asp:PlaceHolder ID="itemPlaceholder" runat="server" />
</tbody>
</table>
<div class="Pagination">
<span>1</span>
<a href="http://.">2</a>
<a href="http://.">3</a>
</div>
</div>
</LayoutTemplate>
<AlternatingItemTemplate>
<tr class="Alternate">
<td><asp:Label ID="movie_idLabel" runat="server"
Text='<%# Eval("movie_id") %>' /></td>
<td><asp:Label ID="titleLabel" runat="server"
Text='<%# Eval("title") %>' /></td>
<td><asp:Label ID="release_dateLabel" runat="server"
Text='<%# Eval("release_date", "{0:d}") %>' /> </td>
</tr>
</AlternatingItemTemplate>
<ItemTemplate>
<tr>
<td><asp:Label ID="movie_idLabel" runat="server"
Text='<%# Eval("movie_id") %>' /></td>
<td><asp:Label ID="titleLabel" runat="server"
Text='<%# Eval("title") %>' /></td>
<td><asp:Label ID="release_dateLabel" runat="server"
Text='<%# Eval("release_date", "{0:d}") %>' /> </td>
</tr>
</ItemTemplate>
</asp:ListView>
分页控件一个常见的应用是在数据网格的顶部和底部提供分页界面,这样用户不必滚动网格就可以导航到下一页——DataPager 能够非常easy做到这一点。
要创建与 ListView 关联的 DataPager 控件。最简单方法是将 DataPager 控件实际嵌入到 ListView 的 LayoutTemplate 中:
<asp:ListView ID="_moviesGrid"
runat="server" DataKeyNames="movie_id"
DataSourceID="_moviesDataSource">
<LayoutTemplate>
<!-- ... -->
<div class="Pagination">
<asp:DataPager ID="_moviesGridDataPager" runat="server">
<Fields>
<asp:NumericPagerField />
</Fields>
</asp:DataPager>
</div>
</LayoutTemplate>
</asp:ListView>
还有一种方法是将 DataPager 放在页面的其他位置,并通过将其 PagedControlID 设置为关联 ListView 的 ID 以便与 ListView 关联。
- NumericPagerField 显示 1 2 3... 分页界面。
- NextPreviousPagerField 显示“Next”(下一页)、“Previous”(上一页)、“First”(第一页)和“Last”(最后一页)button在行间往复。
- TemplatePagerField 让您使用 PagerTemplate 定义精确设计和实现分页接口的功能。
public interface IPageableItemContainer
{
event EventHandler<PageEventArgs> TotalRowCountAvailable;
void SetPageProperties(int startRowIndex, int maximumRows,
bool databind);
int MaximumRows { get; }
int StartRowIndex { get; }
}
假设可以返回总行数。ListView 将检索数据源中的总行数,然后引发 TotalRowCountAvailable 事件,该事件作为其 IPageableItemContainer 接口一部分实现。不论什么关联的 DataPager 控件都将订阅该事件。并使用总行数初始化显示分页界面所需的字段。
DataPager 将随后调用 ListView 的 SetPageProperties 方法设置初始行索引和要返回的最大行数。
不管何时 DataPager 更改其当前页索引(通常因为用户交互),它都将再次调用 ListView 的 SetPageProperties 以反映当前须要检索行的子集。
能够通过设置 DataPager 控件的 PageSize 属性来更改一个页面上显示的记录条数。该属性的值将影响相关 ListView 中设置的最大行数信息。
通过将 QueryStringField 属性设置为某些字符串(比如 pageNum),表示您请求 DataPager 发送 HTTP GET 请求以响应用户单击页面编号的操作,所请求的页面编号将通过您指定字符串的查询字符串參数发送,而不是通过传统的 POST 回发模式发送。
请注意,假设切换到这样的 GET 通信模式。那由 ASP.NET AJAX UpdatePanel 控件使用的 POST 回发挂接机制将无法截取分页请求,并会将其变为异步回发:
<asp:DataPager ID="_moviesGridDataPager" runat="server"
QueryStringField="pageNum" >
<Fields>
<asp:NumericPagerField />
</Fields>
</asp:DataPager>
当然,您能够使用自己定义 DataSource 控件或使用 ObjectDataSource 控件自己定义自己的分页。
<asp:ListView ID="_moviesGrid" runat="server" DataKeyNames="movie_id"
DataSourceID="_moviesDataSource">
<LayoutTemplate>
<div class="PrettyGrid">
<table cellpadding="0" cellspacing="0" summary="">
<thead>
<tr>
<th scope="col">
<asp:LinkButton ID="_movieIdSortLink"
CommandName="Sort" CommandArgument="movie_id"
runat="server">ID</asp:LinkButton>
</th>
<th scope="col">
<asp:LinkButton ID="_titleSortLink"
CommandName="Sort" CommandArgument="title"
runat="server">Title</asp:LinkButton>
</th>
<th scope="col">
<asp:LinkButton ID="_releaseDateSortLink"
CommandName="Sort" CommandArgument="release_date"
runat="server">Release date</asp:LinkButton>
</th>
</tr>
</thead>
<!-- ... -->
</LayoutTemplate>
</asp:ListView>
您能够通过设置 RepeatColumns 属性来控制将基础数据集的多少行归入单个表格行中。
结果如图 11 所看到的。
<asp:ListView ID="_groupListView" runat="server"
DataKeyNames="movie_id" DataSourceID="_moviesDataSource"
GroupItemCount="4" >
<GroupTemplate>
<tr>
<asp:PlaceHolder runat="server" ID="itemPlaceholder" />
</tr>
</GroupTemplate>
<LayoutTemplate>
<table>
<asp:PlaceHolder ID="groupPlaceholder" runat="server" />
</table>
</LayoutTemplate>
<ItemTemplate>
<td>
movie_id:
<asp:Label ID="_movie_idLabel" runat="server"
Text='<%# Eval("movie_id") %>' /> <br />
title:
<asp:Label ID="_titleLabel" runat="server"
Text='<%# Eval("title") %>' /> <br />
release_date:
<asp:Label ID="_release_dateLabel" runat="server"
Text='<%# Eval("release_date", "{0:d}") %>' /> <br />
<br />
</td>
</ItemTemplate>
</asp:ListView>
我想今后我还会很多其它地研究这个灵活的数据绑定控件。
请将您想向 Fritz 询问的问题和提出的意见发送至 xtrmaspt@microsoft.com.
Fritz 这是《Essential ASP.NET》和《Essential ASP.NET 2.0》笔者。
要理解这一点笔者,请登录 pluralsight.com/fritz。