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

ReorderList - 绑定到 DataTable;保存更改

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.14/5 (13投票s)

2007年2月17日

1分钟阅读

viewsIcon

151258

ReorderList 是 ASP.NET AJAX Control Toolkit 中最酷的控件之一。本文旨在提供一个关于如何继承该控件的基本概述,以便将其绑定到 DataTable,并在 Reorder 事件发生时将新的顺序保存到数据库。

引言

ReorderListASP.NET AJAX Control Toolkit 中最酷的控件之一。本文旨在提供一个关于如何继承该控件的基本概述,以便将其绑定到 DataTable,并在 Reorder 事件发生时将新的顺序保存到数据库。本文没有可供下载的源代码,只有代码片段。本文的重点是 ReorderList,而不是从数据库保存和检索数据。

问题

ReorderList 期望其 DataSource 是一个实现 IList 的对象。我的业务对象主要使用 DataSetDataTable,并且我想绑定到一个 DataTable。该控件可以从 DataTable 加载数据,但在 Reorder 事件发生时,会抛出一个异常,指出 DataTable 没有实现 IList。我尝试使用 ((IListSource)DataTable).GetList(),但没有进展。

解决方案

首先,创建 ReorderList 的子类并重写 DoReorder 方法,如下所示

using System;
using System.Data;
using AjaxControlToolkit;

namespace My.Web.UI.Controls
{
    public class myReorderList : ReorderList
    {
        protected override bool DoReorder(int oldIndex, int newIndex)
        {
            if (DataSource is DataTable)
            {
                DataRowCollection rows = ((DataTable)DataSource).Rows;
                int NewListOrder = (int)rows[newIndex][SortOrderField];

                if (oldIndex < newIndex) //item moved down

                {
                    for (int i = oldIndex + 1; i <= newIndex; i++)
                    {
                        rows[i][SortOrderField] = 
                    (int)rows[i][SortOrderField] - 1;
                    }
                }
                else  //item moved up

                {
                    for (int i = oldIndex - 1; i >= newIndex; i--)
                    {
                        rows[i][SortOrderField] = 
                    (int)rows[i][SortOrderField] + 1;
                    }
                }
                rows[oldIndex][SortOrderField] = NewListOrder;
                return true;
            }
            else
            {
                throw new InvalidOperationException
            ("DataSource is not a System.Data.DataTable.");
            }
            return false;
        }
    }
}

这里是一个 aspx 页面的示例代码,它与 ASP.NET AJAX Control Toolkit 的 Samples 项目中的 ReorderList.aspx 中的代码几乎完全相同。唯一的例外是添加了 OnItemReorder="ReorderList1_ItemReorder"。 另外请注意 SortOrderField="Priority"。 这表示数据源 DataTable 中存储项目组内顺序的列的名称。 此属性在上面引用的子类中重写的 DoReorder 方法中使用,以存储新的顺序。子类化的控件期望此列是一个 int 列。

<MyAjaxToolkit:myReorderList ID="ReorderList1" runat="server"
    PostBackOnReorder="false"
    CallbackCssStyle="callbackStyle"
    DragHandleAlignment="Left"
    ItemInsertLocation="End"
    DataKeyField="ItemID"
    SortOrderField="Priority"
    OnItemReorder="ReorderList1_ItemReorder">
    <ItemTemplate>
        <div class="itemArea">
            <asp:Label ID="Label1" runat="server"
                Text='<%# HttpUtility.HtmlEncode(Convert.ToString(Eval("Title"))) %>' />
            <asp:Label ID="Label2" runat="server"
                Text='<%# HttpUtility.HtmlEncode(Convert.ToString(Eval("Description", " - {0}"))) %>' />
        </div>
    </ItemTemplate>
    <EditItemTemplate>
        <div class="itemArea">
            <asp:TextBox ID="TextBox2" runat="server" Text='<%# Bind("Title") %>' />
            <asp:TextBox ID="TextBox3" runat="server" Text='<%# Bind("Description") %>' />
            <asp:TextBox ID="TextBox4" runat="server" Text='<%# Bind("Priority") %>' />
        </div>
    </EditItemTemplate>
    <ReorderTemplate>
        <asp:Panel ID="Panel2" runat="server" CssClass="reorderCue" />
    </ReorderTemplate>
    <DragHandleTemplate>
        <div class="dragHandle"></div>
    </DragHandleTemplate>
    <InsertItemTemplate>
        <!-- bottom border is workaround for IE7 Beta issue where bg doesn't render -->
        <div style="padding-left:25px; border-bottom:thin solid transparent;">
            <asp:Panel ID="panel1" runat="server" DefaultButton="Button1">
                <asp:TextBox ID="TextBox1" runat="server" Text='<%# Bind("Title") %>' />
                <asp:Button ID="Button1" runat="server" CommandName="Insert" Text="Add" />
                <asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server"
                    ErrorMessage="Please enter some text" ControlToValidate="TextBox1" />
            </asp:Panel>
        </div>
    </InsertItemTemplate>
</MyAjaxToolkit:myReorderList>

然后在 aspx 页面的代码隐藏文件中,我们需要类似以下内容

protected void Page_Load(object sender, EventArgs e)
{
    ReorderList1.ItemDataBound += 
    new EventHandler<AjaxControlToolkit.ReorderListItemEventArgs>
                    (ReorderList1_ItemDataBound);
    if (!IsPostBack)
    {
        BindReorderList();
    }
    else
    {
        // Need code here to retrieve the data source DataTable from

        // the Session object or other persistence method and assign it to

        // ReorderList1.DataSource property

    }
}

void BindReorderList()
{
    // Need code here to fill SomeDataTable with a DataTable.

    // It must contain an int column named in the SortOrderField

    // property of the myReorderList control markup in the aspx page


    ReorderList1.DataSource = SomeDataTable;
    ReorderList1.DataBind();

    //Need to save SomeDataTable to the Session object or 

    //other persistence method

}

protected void ReorderList1_ItemReorder(object sender, 
        AjaxControlToolkit.ReorderListItemReorderEventArgs e)
{
    // need code to save changes made to the data source DataTable

    // The changes were made in the overridden DoReorder method

    // in the MyReorderList control


    BindReorderList();
}
© . All rights reserved.