使用 ASP.NET AJAX Control Toolkit 的 ReorderList 控件和 LINQ to SQL 实现实时排序
一篇关于将 LINQ to SQL 与 ASP.NET AJAX Control Toolkit 的 ReorderList 控件结合使用的文章。
引言
ReorderList
是 ASP.NET AJAX Control Toolkit 中一个非常强大的组件。它使您能够交互式地重新排序列表中的项目。
问题
我创建了这个演示,以介绍如何将 ASP.NET AJAX Toolkit 的 ReorderList
控件连接到 LINQ to SQL 数据源。默认情况下,ReorderList
控件使您能够轻松地在客户端重新排序列表中的项目。我发现它不足之处在于如何将您所做的重新排序更改提交回数据库。
解决方案
我在重新排序事件发生时创建了一种相当直接的方法来将重新排序的更改提交回数据库。通过这样做,您所做的重新排序更改将实时提交到数据库,而不是进行大量更改并单击“重新排序”按钮。我认为这是一种更好的方法,因为更改丢失的几率较低,并且这有助于解决多用户重新排序场景中的争用问题。
网页
<%@ Page Language="C#" AutoEventWireup="true"
CodeBehind="RealtimeReorderList.aspx.cs"
Inherits="RealtimeReorderlist.RealtimeReorderList" %>
<%@ Register Assembly="AjaxControlToolkit"
Namespace="AjaxControlToolkit" TagPrefix="ajaxToolkit" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<link rel="Stylesheet" type="text/css"
href="ReorderList.css" />
<title>Realtime Reorderable List Using LINQ to SQL</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:ScriptManager ID="ScriptManager1" runat="server" />
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<fieldset>
<legend>Reorderable List Items</legend>
<div style="width: 850px">
<div class="reorderListDemo"
style="padding-bottom: 50px">
<ajaxToolkit:ReorderList ID="rlItemList"
DragHandleAlignment="Left"
PostBackOnReorder="true"
CallbackCssStyle="callbackStyle"
ItemInsertLocation="End"
ShowInsertItem="false"
runat="server">
<DragHandleTemplate>
<div class="dragHandle">
</div>
</DragHandleTemplate>
<ItemTemplate>
<div class="itemArea">
<span style="float: right">
<asp:Button Width="50" ID="Button3"
CommandName="Delete"
runat="server" Text="Delete" />
</span>
<asp:Label ID="ID" Visible="false"
runat="server"
Text='<%# Eval("ID") %>'></asp:Label>
<asp:Label ID="Order" Visible="false"
runat="server"
Text='<%# Eval("ListOrder") %>'></asp:Label>
<asp:Label ID="Name" runat="server"
Text='<%# Eval("Name") %>'></asp:Label>:
<asp:Label ID="Label1" runat="server"
Text='<%# Eval("Description") %>'></asp:Label>
</div>
</ItemTemplate>
<ReorderTemplate>
<asp:Panel ID="Panel2" runat="server"
CssClass="reorderCue" />
</ReorderTemplate>
</ajaxToolkit:ReorderList>
</div>
</div>
</fieldset>
<fieldset>
<legend>Add List Item</legend>
<div>
<asp:TextBox ID="tbItemName"
runat="server"></asp:TextBox>
<ajaxToolkit:TextBoxWatermarkExtender ID="TBWE1"
runat="server" TargetControlID="tbItemName"
WatermarkText="Name"
WatermarkCssClass="watermarkTextBox" />
</div>
<div>
<asp:TextBox Rows="4" ID="tbItemDescription"
runat="server" Height="51px"
TextMode="MultiLine"></asp:TextBox>
<ajaxToolkit:TextBoxWatermarkExtender ID="TBWE2"
runat="server"
TargetControlID="tbItemDescription"
WatermarkText="Description"
WatermarkCssClass="watermarkTextBox" />
</div>
<div>
<asp:Button ID="btnAddReorderListItem"
runat="server" Text="Add"
OnClick="AddReorderListItem_Click" />
</div>
</fieldset>
</ContentTemplate>
</asp:UpdatePanel>
</div>
</form>
</body>
</html>
代码隐藏部分
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using AjaxControlToolkit;
namespace RealtimeReorderlist
{
public partial class RealtimeReorderList : System.Web.UI.Page
{
protected int NewListOrderNumber;
protected List<reorderlistitem> ListDataItems;
protected void Page_Load(object sender, EventArgs e)
{
rlItemList.ItemReorder += new EventHandler<reorderlistitemreordereventargs>
(rlItemList_ItemReorder);
// Event handler for deleting items from the list
rlItemList.ItemCommand += new EventHandler<reorderlistcommandeventargs>
(rlItemList_ItemCommand);
GetListData();
if (!Page.IsPostBack)
BindData();
}
/// <summary>
/// Reorder list items in the database when a reorder event occurs
/// </summary>
protected void rlItemList_ItemReorder(object sender,
ReorderListItemReorderEventArgs e)
{
var NewOrder = e.NewIndex + 1;
var OldOrder = e.OldIndex + 1;
var ReorderListItemID = Convert.ToInt32(((Label)(
e.Item.FindControl("ID"))).Text);
var db = new RealTimeReorderListDataDataContext();
var ListItemCount = 1;
var ListData = from ld in db.ReorderListItems
orderby ld.ListOrder
select ld;
foreach (var ListDataItem in ListData)
{
// Move forward items in this range
if (OldOrder > NewOrder
&& ListItemCount >= NewOrder
&& ListItemCount <= OldOrder
)
ListDataItem.ListOrder = ListItemCount + 1;
// Move backward items in this range
else if
(OldOrder < NewOrder
&& ListItemCount <= NewOrder
&& ListItemCount >= OldOrder
)
ListDataItem.ListOrder = ListItemCount - 1;
ListItemCount++;
// Set the changed item into the newly numerical gap
if (ListDataItem.ID == ReorderListItemID)
ListDataItem.ListOrder = NewOrder;
}
db.SubmitChanges();
GetListData();
BindData();
}
/// <summary>
/// ItemCommand event used to delete list items
/// </summary>
void rlItemList_ItemCommand(object sender, ReorderListCommandEventArgs e)
{
// If you want support for multiple commands
if (e.CommandName != "Delete")
return;
var db = new RealTimeReorderListDataDataContext();
var ListData = from ld in db.ReorderListItems
where ld.ID == Convert.ToInt32(((Label)
(e.Item.FindControl("ID"))).Text)
select ld;
db.ReorderListItems.DeleteAllOnSubmit(ListData);
db.SubmitChanges();
GetListData();
BindData();
}
/// <summary>
/// Add button click event used to inset a new list item into the database
/// </summary>
protected void AddReorderListItem_Click(object sender, EventArgs e)
{
GetListData(); // Get the current NewListOrderNumber
var db = new RealTimeReorderListDataDataContext();
var RLI = new ReorderListItem
{
ListOrder = NewListOrderNumber,
Name = tbItemName.Text,
Description = tbItemDescription.Text
};
db.ReorderListItems.InsertOnSubmit(RLI);
db.SubmitChanges();
// Clear the form values so that watermark shows
tbItemName.Text = "";
tbItemDescription.Text = "";
GetListData(); //Get the list with the newly inserted item
BindData();
}
/// <summary>
/// Retrieve the list items from the database
/// </summary>
protected void GetListData()
{
var db = new RealTimeReorderListDataDataContext();
var ListData = from ld in db.ReorderListItems
orderby ld.ListOrder
select ld;
ListDataItems = ListData.ToList();
NewListOrderNumber = ListDataItems.Count() + 1;
}
/// <summary>
/// Bind the data the to the ReorderList control
/// </summary>
protected void BindData()
{
rlItemList.DataSource = ListDataItems;
rlItemList.DataBind();
}
}
}
SQL 模式
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[ReorderList](
[ID] [int] IDENTITY(1,1) NOT NULL,
[ListOrder] [int] NULL,
[Name] [nvarchar](256) NULL,
[Description] [nvarchar](4000) NULL,
CONSTRAINT [PK_ReorderList] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]