此處介紹的情境是:
(1)使用table布局ListView。
(2)ListView的數據源是List<T>。
(3)排序字段2個(帖子的回復次數和浏覽次數),都是int類型。
基本思路:
ListView觸發數據源排序,使用數據源(即List<T>)的Sort()方法,重新綁定數據源到ListView。
實現步驟:
(1)可查知,List<T>的Sort()方法帶有一個ICompare<T>泛型接口類型的形參。所以,首先構造繼承該泛型接口的類型:
[csharp]
/// <summary>
/// 回復升序比較類
/// </summary>
public class PostReplyCountAscCompare : IComparer<PostInfo>
{
#region IComparer<PostInfo> 成員
public int Compare(PostInfo x, PostInfo y)
{
return x.ReplyCount.CompareTo(y.ReplyCount);
}
#endregion
}
/// <summary>
/// 回復降序比較類
/// </summary>
public class PostReplyCountDescCompare : IComparer<PostInfo>
{
#region IComparer<PostInfo> 成員
public int Compare(PostInfo x, PostInfo y)
{
return y.ReplyCount.CompareTo(x.ReplyCount);
}
#endregion
}
/// <summary>
/// 浏覽升序比較類
/// </summary>
public class PostViewCountAscCompare : IComparer<PostInfo>
{
#region IComparer<PostInfo> 成員
public int Compare(PostInfo x, PostInfo y)
{
return x.ViewCount.CompareTo(y.ViewCount);
}
#endregion
}
/// <summary>
/// 浏覽降序比較類
/// </summary>
public class PostViewCountDescCompare : IComparer<PostInfo>
{
#region IComparer<PostInfo> 成員
public int Compare(PostInfo x, PostInfo y)
{
return y.ViewCount.CompareTo(x.ViewCount);
}
#endregion
}
注意:上述的PostInfo模型類,讀者可以杜撰,但要有ViewCount和ReplyCount屬性(int類型)。
(2)由於有4個排序規則,對應上述(1)中的4個類。所以構造一個排序輔助類:SortHelper,代碼如下:
[csharp]
public class SortHelper
{
/// <summary>
/// 對集合進行排序——泛型方法
/// </summary>
/// <typeparam name="T1">集合中的對象類型</typeparam>
/// <typeparam name="T2">排序類型</typeparam>
/// <param name="collection">要排序的集合</param>
/// <param name="comparer">排序器</param>
public static void Sort<T1,T2>(List<T1> collection,T2 comparer) where T2:IComparer<T1>
{
collection.Sort(comparer);
}
}
(3)設計ListView,構造排序字段
[html]
<LayoutTemplate>
<table class="PostList">
<tr class="PostListHeader">
<td colspan="2">
標題
</td>
<td>
發布日期
</td>
<td>
<asp:LinkButton runat="server" ID="lbtnReply" Text="回復" CommandName="Sort" CommandArgument="ReplyCount"
CssClass="sortLink"></asp:LinkButton>
</td>
<td>
<asp:LinkButton runat="server" ID="lbtnView" Text="浏覽" CommandName="Sort" CommandArgument="ViewCount"
CssClass="sortLink"></asp:LinkButton>
</td>
<td>
最後發表
</td>
<td>
刪除
</td>
</tr>
<tr runat="server" id="itemPlaceholder">
</tr>
</table>
<div class="pager">
<asp:DataPager ID="pagerBottom" runat="server" PageSize="5">
<Fields>
<asp:NextPreviousPagerField ButtonCssClass="command" FirstPageText="<<" PreviousPageText="<"
RenderDisabledButtonsAsLabels="true" ShowFirstPageButton="true" ShowLastPageButton="false"
ShowNextPageButton="false" ShowPreviousPageButton="true" />
<asp:NumericPagerField ButtonCount="7" CurrentPageLabelCssClass="current" NextPreviousButtonCssClass="command"
NumericButtonCssClass="command" />
<asp:NextPreviousPagerField ButtonCssClass="command" LastPageText=">>" NextPageText=">"
RenderDisabledButtonsAsLabels="true" ShowFirstPageButton="false" ShowLastPageButton="true"
ShowNextPageButton="true" ShowPreviousPageButton="false" />
</Fields>
</asp:DataPager>
</div>
</LayoutTemplate>
注意:上面LayoutTemplate中的兩個LinkButton,用來作為用戶排序接口。其CommandName屬性為Sort(固定),CommandArgument分別為ReplyCount和ViewCount。
(4)ListView公開了兩個與排序相關的事件:Sorting和Sorted。
[csharp] view plaincopy
/// <summary>
/// listview排序
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void lvPosts_Sorting(object sender, ListViewSortEventArgs e)
{
//判斷是否指定了排序字段
if (string.IsNullOrEmpty(e.SortExpression))
{
return;
}
//數據源
if (ViewState["posts"] != null)
{
posts = ViewState["posts"] as List<PostInfo>;
}
else
{
posts = new PostInfoBLL().GetAllPosts(begin, end);
ViewState["posts"] = posts;
}
//升序還是降序
if (ViewState["SortDirection"] != null)
{
e.SortDirection=(SortDirection)ViewState["SortDirection"];
}
//按哪個字段排序
if (e.SortExpression == "ReplyCount")
{
if (e.SortDirection == SortDirection.Ascending)
{
//泛型方法調用
SortHelper.Sort<PostInfo, PostReplyCountAscCompare>(posts, new PostReplyCountAscCompare());
ViewState["SortDirection"] = SortDirection.Descending;
}
else
{
SortHelper.Sort<PostInfo, PostReplyCountDescCompare>(posts, new PostReplyCountDescCompare());
ViewState["SortDirection"] = SortDirection.Ascending;
}
}
else if (e.SortExpression == "ViewCount")
{
if (e.SortDirection == SortDirection.Ascending)
{
SortHelper.Sort<PostInfo,PostViewCountAscCompare>(posts, new PostViewCountAscCompare());
ViewState["SortDirection"] = SortDirection.Descending;
}
else
{
SortHelper.Sort<PostInfo,PostViewCountDescCompare>(posts, new PostViewCountDescCompare());
ViewState["SortDirection"] = SortDirection.Ascending;
}
}
BindPosts(true);
}
注意:上述方法中的數據源的獲取和BindPosts()方法,讀者可自行杜撰。
(5)運行界面如下圖: