65.9K
CodeProject 正在变化。 阅读更多。
Home

持久化对 ReorderList 所做的更改

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.43/5 (3投票s)

2007 年 6 月 26 日

2分钟阅读

viewsIcon

63983

downloadIcon

557

本文演示了一种保存对 ReorderList 中呈现的初始顺序所做的更改的方法

Screenshot - PersistentReorderList1.jpg

引言

本文演示了如何使用 ASP.NET AJAX ReorderList,并能够检索和保存对其所做的更改。

背景

ReorderList 控件在跨浏览器体验方面提供了非常流畅的拖放列表项功能。然而,它与其他大多数控件的行为截然不同,即访问列表所做的更改没有内置属性,需要一些特殊的处理!

我希望向我页面的访问者展示一个列表,并允许他们根据需要重新排序,并在页面提交时保存更改后的顺序。然而,在浏览互联网时,我很难找到一个明确的解决方案。我希望这篇文章能帮助那些有类似需求的人。

使用代码

本文将根据代码进行描述。为了更好地理解,我将代码分成以下必要的几个部分:

  1. 数据库
  2. WorkItemWorkItemsHandler
  3. ReorderList 标记代码
  4. EventHandler 代码

数据库

我的示例数据库只有一个名为 WorkItems 的表,包含以下示例数据:

Screenshot - PersistentReorderList2.jpg


请注意,Priority 列决定了初始呈现顺序。

WorkItemWorkItemsHandler

/////////////////////////////////////////////
/// 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 />";
    }
}

重要问题

  1. ReorderList 的 DataSource 需要实现 IList。因此,如果您提供一个 DataTable,它将表现出意想不到的行为。它会第一次显示,但在后续的 post-back 中会抛出异常。
  2. 如果适用,可以选择 Application 集合 (HttpContext.Current.Application) 或 Cache (HttpContext.Current.Cache) 代替 Session。
  3. 必须注册 OnItemReorder,并且必须在此事件处理程序中进行持久化机制。

历史

  • 2007 年 6 月 24 日 - 初始编写
© . All rights reserved.