在开发数据绑定的网格控件时,ListView提供了一种简化复杂HTML的方法。它允许开发者完全控制生成的HTML,同时还提供了简化的数据绑定、自定义分页和列排序功能。虽然ListView提供了列排序功能,但它并没有明确指示最近排序的列。网络上有许多技术用于提供DataGrid和GridView的列排序指示器。本文的目的是提供一个自定义控件,用于提供ListView列排序指示器。
这个ListView列排序指示器由两个自定义控件组成:一个是从ListView继承的ListViewSort自定义控件,以及一个用于定义ListView LayoutTemplate中每个可排序标题的ListViewSortColumnHeader复合自定义控件。ListViewSort自定义控件用于替换ListViewASP.NET控件,并公开以下扩展公共属性:
除了上述扩展公共属性外,ListViewSort与ListView相同,如下所示:
<myControls:ListViewSort ID="listViewSort" DataSourceID="ObjMenu" DataKeyNames="Name" SortExpressionDefault="Name" SortDirectionDefault="Ascending" runat="server">
<LayoutTemplate>
<table runat="server" class="listViewGrid" cellspacing="0" border="0">
<tr>
<th>
<myControls:ListViewSortColumnHeader runat="server" Key="Name" Text="食品名称" />
</th>
<th>
<myControls:ListViewSortColumnHeader runat="server" Key="Price" Text="价格" />
</th>
<th>
<myControls:ListViewSortColumnHeader runat="server" Key="Description" Text="描述" />
</th>
<th>
<myControls:ListViewSortColumnHeader runat="server" Key="Calories" Text="卡路里" />
</th>
</tr>
<tr runat="server" id="itemPlaceholder" />
</table>
</LayoutTemplate>
<ItemTemplate>
<tr class="<%# ((ListViewDataItem)Container).DisplayIndex % 2 == 0 ? "itemRow" : "altItemRow" %>">
ListViewSortColumnHeader复合控件用于替换通常用于激活列排序的HyperLinkASP.NET控件。ListViewSortColumnHeader公开Key和Text属性。Key属性将标题与数据绑定表达式关联起来,而Text属性提供了标题中显示的实际文本。ListViewSortColumnHeader控件本质上生成了asp:HyperLink控件和一个asp:PlaceHolder控件,用于在标题参与排序操作时预期的asp:Image控件。
ListViewSort自定义控件覆盖了从ListView继承的单个事件OnDataBound,如下所示:
protected override void OnDataBound(EventArgs e) {
if (base.SortExpression.Length == 0) {
if (SortExpressionDefault.Length > 0) {
base.Sort(SortExpressionDefault, SortDirectionDefault);
}
}
List<Control> controls = Helpers.GetControlsByType(this, typeof(ListViewSortColumnHeader));
foreach (Control control in controls) {
ListViewSortColumnHeader header = (ListViewSortColumnHeader)control;
if (header.HasSortDirectionIndicator() == true) {
header.ResetSortDirectionIndicator();
}
}
foreach (Control control in controls) {
ListViewSortColumnHeader header = (ListViewSortColumnHeader)control;
if (header.Key == base.SortExpression) {
header.SetSortDirectionIndicator(base.SortExpression, base.SortDirection);
break;
}
}
base.OnDataBound(e);
}
在ListViewSort OnDataBound事件处理过程中,现有的ListViewSort标题被检查,任何现有的排序方向指示asp:Image控件被移除,然后适当的排序方向指示asp:Image控件被注入到新的被排序的标题中。除了在ViewState中维护ListViewSort的四个扩展公共属性之外,ListViewSort基本上就是这样。这种级别的简单性确保排序方向指示逻辑不需要在每个使用ListView的Web页面中进入应用程序。