持久化对 ASP.NET AJAX ReorderList 所做的更改






3.45/5 (8投票s)
ASP.NET AJAX ReorderList 没有内置属性来检索客户端所做的更改。本文展示了解决此问题的方法。
引言
本文演示了如何使用 ASP.NET AJAX ReorderList
,并具有检索/保存对其所做更改的功能。
背景
ReorderList
控制提供了一个非常流畅的跨浏览器体验,具有可拖动列表项。但是,它与其他大多数控件的行为有所不同,即访问对列表所做的更改不是内置功能,需要一些特殊处理! 我想在我的页面上显示一个访客列表,根据需要对其进行重新排序,并在页面提交时保存更改后的顺序。 但是,在网上搜索时,我很难找到一个明确的解决方案。 我希望本文能帮助那些有类似需求的人。
使用代码
本文将根据代码进行描述,为了更好地理解,我将代码分成以下必要的几个部分:
- 数据库
WorkItem
和WorkItemsHandler
类ReorderList
标记代码EventHandler
代码
1. 数据库
我的示例数据库只有一个名为 WorkItems 的表,包含以下示例数据
注意: Priority
列决定了初始呈现顺序(升序)。
2. WorkItem 和 WorkItemsHelper 类
/////////////////////////////////////////////
/// Code fragment from App_Code/WorkItem.cs
/////////////////////////////////////////////
public class WorkItem
{
public WorkItem(int itemID, int priority, string title, string description)
{
_ItemID = itemID;
_Priority = priority;
_Title = title;
_Description = description;
}
private int _ItemID;
public int ItemID
{
get { return _ItemID; }
set { _ItemID = value; }
}
private int _Priority;
public int Priority
{
get { return _Priority; }
set { _Priority = value; }
}
private string _Title;
public string Title
{
get { return _Title; }
set { _Title = value; }
}
private string _Description;
public string Description
{
get { return _Description; }
set { _Description = value; }
}
public override string ToString()
{
return string.Format("Item: ID:{0}\tPriority:{1}\tTitle{2}" +
"\tDecription{3}", _ItemID, _Priority, _Title, _Description);
}
}
/////////////////////////////////////////////
/// Code fragment from App_Code/WorkItemsHelper.cs
/////////////////////////////////////////////
public class WorkItemsHelper
{
//Loads the Work items to the Session Scope
public static void LoadWorkItems()
{
HttpContext.Current.Session["WorkItems"] =
WorkItemsHelper.GetWorkItems();
}
//Returns the WorkItems - either from database
// or from Session scope (if its there!)
public static List<WorkItem> GetWorkItems()
{
if (HttpContext.Current.Session["WorkItems"] == null)
{
DataTable table = new WorkItemsTableAdapter().GetWorkItems();
List<WorkItem> workItems = new List<WorkItem>();
foreach (DataRow row in table.Rows)
{
workItems.Add(new WorkItem(int.Parse(row["ItemID"].ToString()),
int.Parse(row["Priority"].ToString()),
row["Title"].ToString(),
row["Description"].ToString()));
}
return workItems;
}
return (List<WorkItem>)HttpContext.Current.Session["WorkItems"];
}
//Save the workItems to the Session Scope
public static void SaveWorkItems(List<WorkItem> workItems)
{
HttpContext.Current.Session["WorkItems"] = workItems;
}
}
3. ReorderList 标记代码
<div class="ClsReorderListContainer">
<ajaxToolkit:ReorderList ID="rlWorkItems" runat="server" DragHandleAlignment="Left"
ItemInsertLocation="Beginning" DataKeyField="ItemID" SortOrderField="Priority"
EnableViewState="true" OnItemReorder="rlWorkItems_ItemReorder"
CallbackCssStyle="ClsCallBackStyle">
<ItemTemplate>
<div class="ClsItemArea">
<table style="width: 100%;">
<tr>
<td class="ClsItem">
<asp:Label ID="Title" runat="server"
Text='<%# Eval("Title") %>'></asp:Label>
<asp:Label ID="Description" runat="server"
Text='<%# Eval("Description") %>'></asp:Label>
</td>
</tr>
</table>
</div>
</ItemTemplate>
<ReorderTemplate>
<asp:Panel ID="Panel2" runat="server" CssClass="ClsReorderCue">
</asp:Panel>
</ReorderTemplate>
<DragHandleTemplate>
<div class="ClsDragHandle">
</div>
</DragHandleTemplate>
</ajaxToolkit:ReorderList>
</div>
4. EventHandler 代码
此示例应用程序需要处理以下事件才能正常运行
Session_Start
:将WorkItem
s 加载到当前会话中。
void Session_Start(object sender, EventArgs e)
{
// Load WorkItems to the current session.
WorkItemsHelper.LoadWorkItems();
}
Page_Load
:每次页面加载时,将 ReorderList
与数据绑定。protected void Page_Load(object sender, EventArgs e)
{
//Bind the ReorderList - its a must
rlWorkItems.DataSource = WorkItemsHelper.GetWorkItems();
rlWorkItems.DataBind();
}
rlWorkItems_ItemReorder
:在客户端更改时保存新的顺序。protected void rlWorkItems_ItemReorder(object sender,
AjaxControlToolkit.ReorderListItemReorderEventArgs e)
{
//Item Reordered, so save the current order to the Session scope
WorkItemsHelper.SaveWorkItems((List<WorkItem>)rlWorkItems.DataSource);
}
btnSubmit_Click
:将新的顺序显示到浏览器。protected void btnSubmit_Click(object sender, EventArgs e)
{
//Show the current order
divMessage.InnerHtml = "New Order <hr />";
foreach (WorkItem item in WorkItemsHelper.GetWorkItems())
{
divMessage.InnerHtml += item.ToString()+"<br />";
}
}
重要问题
ReorderList
的DataSource
需要实现IList
。 因此,提供一个DataTable
会表现出意想不到的行为,并且第一次会显示错误,但在后续的 postback 中才会抛出异常。- 如果适用,可以选择
Application
集合 (HttpContext.Current.Application
) 或Cache
(HttpContext.Current.Cache
) 代替Session
。 - 必须注册
OnItemReorder
,并且持久化机制必须在此事件处理程序中进行。
历史
- 2007 年 6 月 24 日 - 初始撰写日期。