持久化对 ReorderList 所做的更改






4.43/5 (3投票s)
2007 年 6 月 26 日
2分钟阅读

63983

557
本文演示了一种保存对 ReorderList 中呈现的初始顺序所做的更改的方法
引言
本文演示了如何使用 ASP.NET AJAX ReorderList,并能够检索和保存对其所做的更改。
背景
ReorderList 控件在跨浏览器体验方面提供了非常流畅的拖放列表项功能。然而,它与其他大多数控件的行为截然不同,即访问列表所做的更改没有内置属性,需要一些特殊的处理!
我希望向我页面的访问者展示一个列表,并允许他们根据需要重新排序,并在页面提交时保存更改后的顺序。然而,在浏览互联网时,我很难找到一个明确的解决方案。我希望这篇文章能帮助那些有类似需求的人。
使用代码
本文将根据代码进行描述。为了更好地理解,我将代码分成以下必要的几个部分:
- 数据库
WorkItem
和WorkItemsHandler
类- ReorderList 标记代码
- EventHandler 代码
数据库
我的示例数据库只有一个名为 WorkItems 的表,包含以下示例数据:
请注意,Priority 列决定了初始呈现顺序。
WorkItem
和 WorkItemsHandler
类
/////////////////////////////////////////////
/// 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 SessionScope
public static void SaveWorkItems(List<WorkItem> workItems)
{
HttpContext.Current.Session["WorkItems"] = workItems;
}
}
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>
EventHandler 代码
示例应用程序为了正常运行,会处理以下事件:
Session_Start
Session_Start
将 WorkItems 加载到当前会话中,如下所示:
void Session_Start(object sender, EventArgs e)
{
// Load WorkItems to the current session.
WorkItemsHelper.LoadWorkItems();
}
Page_Load
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
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
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,它将表现出意想不到的行为。它会第一次显示,但在后续的 post-back 中会抛出异常。 - 如果适用,可以选择 Application 集合 (
HttpContext.Current.Application
) 或 Cache (HttpContext.Current.Cache
) 代替 Session。 - 必须注册
OnItemReorder
,并且必须在此事件处理程序中进行持久化机制。
历史
- 2007 年 6 月 24 日 - 初始编写