使用自定义DataGrid类进行排序和分页

分享于 

13分钟阅读

Web开发

  繁體

介绍

ASP.NET DataGrid 是一个强大的组件,利用排序和分页功能非常简单,只需要添加几行代码。 但是作为类库生成器,我希望有一个 DataGrid 类,它有排序和分页的所有特性,这样程序员就不必编写代码。 除了原始版本的绑定列之外,文章的更新版本还提供了超链接列和模板列的排序功能。

使用代码

DLL包含以下类: CmdButtonFormSPDataGridDataGridNavigationBarOridinalProvider。 添加了对DLL的引用并将DLL添加到工具箱后,可以将后两个控件拖放到设计模式中。 HTML代码应包含对代码 below 中给定的DLL的引用:

<%@RegisterTagPrefix="ntm"Namespace="NTM.Controls"Assembly="SPDataGrid"%>

你的网页应该从 CmdButtonForm 类继承,如下所示:

publicclass WebForm1 : NTM.Controls.CmdButtonForm

你可以使用 SPDataGrid 类的排序和分页特性,或者只使用其中之一。 首先,应该正确设置 ConnectionStr 属性(。当然,指定连接字符串)。 若要填充 DataGrid,请调用 Populate public 方法。 它只有一个参数,即 SQLSelectStr,它包含 选择 用于排序特性的属性包括:

  • ListOfSortableColumns: 一个逗号分隔字符串,包含要作排序的列的零索引( 比如。 "0,1,3,4")。如果要使 DataGrid 中的所有列都可以排序,请设置 ListOfSortableColumns ="all"
  • InitialSortingColumnIndex: 你最初要排序的列的从零开始的索引。 默认值 -1表示 DataGrid 内容在调用 Populate 方法时不会在第一次排序时进行排序。 注意,初始排序列可能不在可以排序列的列表中。
  • InitialSortingDirection: DESC ( 结尾) 或者任何其他值均意味着升序。
  • myOrdinalProvider: 协作序号提供程序对象。 如果不指定这里选项,默认 OrdinalProvider 将单步执行。 检查排序部分下的详细信息。

你应该设置 AllowPaging ="true"" 如果你想使用分页功能。 分页功能一起使用的属性包括:

  • NavigationBarControl: 协作导航栏。 对于使用原版本的人,请注意使用了 NavigationBarControlID,现在已经替换了这个属性。
  • InitialPageSize: 每个页面的初始大小。 默认值为 20.

你可以根据需要在页面中添加任意数量的SPDataGrid。 你还可以查看演示项目,以了解如何使用组件。 它与 SQL Server的NorthWind数据库一起工作。

Points of interest

什么是CmdButtonForm类?

当你想要使用 DataGrid的时候,你可能想知道 CmdButtonForm 类在这里做什么。 实际上,这就是在类库级别处理页面 Having 多个提交按钮时我通常使用的技巧。 页面将添加一些隐藏字段,并且每个提交按钮将在提交之前修改它们的值。 在本文中,我使用了两个隐藏字段来存储命令和提交的命令参数。 CmdButtonForm 类还将添加这里提交机制所必需的客户端代码。 让我们再仔细看看。 生成的JavaScript代码将如下所示:

function __SetCmd(cmd, param)
{
 var CmdTag = document.getElementById('__Cmd');
 var ParamTag = document.getElementById('__CmdParam');
 if (CmdTag!= null)
 CmdTag.value=cmd;
 if (ParamTag!= null)
 ParamTag.value=param;
}

页面上每个提交按钮的JavaScript OnClick 事件处理程序将调用 __SetCmd 函数 上面。 例如附加到 SPDataGrid2DataGrid的导航栏的第一个按钮将具有以下JavaScript事件处理程序:

OnClick="__SetCmd('DG_NAV_F','SPDataGrid2');"

提交页面时,服务器端将检查隐藏字段的值,如果必要,将检查命令的值,如下代码所示:

protectedoverridevoid OnLoad(EventArgs e)
{ 
. . .
 string Command = GetInputHiddenValue("__Cmd"); 
 string CommandParam = GetInputHiddenValue("__CmdParam"); 
 if (CommandParam.Length>0) 
 {
 string ControlID = "";
 int nOff = CommandParam.IndexOf("$"); 
 if (nOff>0)
 { 
 ControlID = CommandParam.Substring(0,nOff); 
 CommandParam = CommandParam.Substring(nOff+1);
 } 
 else 
 {
 ControlID = CommandParam; 
 CommandParam = "";
 }
 if (ControlID.Equals(this.ID)) 
 {
 ExecuteCmd(Command, CommandParam);
 } 
 }
. . .
}

正如你可以看到的,DataGrid 将检查 Command 参数,以查看该命令是否将被执行。 如果命令有多个参数,则参数将被连接到一个带有预定义分隔符( 在我们的例子中,是美元符号( $ )的字符串中。 谈谈真正面向对象的封装,如果 DataGrid 类可以自己添加这些隐藏字段而不是容器页类。 但是,.NET 将引发一个异常,说明: "控件不能修改其父级的'控件集合",如果你尝试这样做。

SPDataGrid类

SPDataGrid 类使用ViewState存储一些数据,这些数据应该保存在请求中。 这些持久化数据之一是 SQL 选择Populate 方法中设置该语句,直到调用下一个 Populate

排序

不像其他. NET 排序示例,我使用数据库引擎的排序特性,而不是利用 DataView.Sort 方法提供的.NET 平台的排序特性。 我相信这种排序方法可以在处理大型数据集时提供更好的性能,尤它的是在。 不过,我没有时间测试和测量它,如果你与我分享与这里事相关的经验,我会非常高兴。 SPDataGrid 类需要有关SQL中每个( 可以排序) 列的序号的信息 选择 语句,以便对它的内容进行排序,而 OrdinalProvider 类( 最新介绍的1.1版本) 则提供该信息。 这个 SPDataGrid 类在column的每个排序图像的JavaScript OnClick 事件处理程序中都包含这里信息,因此当单击 image image class class know用户希望将内容排序到哪个列。 现在让我们来看看 OrdinalProvider 类在默认情况下如何提供这里信息。 对于 BoundColumn,它接受每个列的DataField 属性并根据SQL对它的进行检查 选择 语句以获取列的序号,该列 选择 语句。使用 HyperLinkColumnDataTextField 属性将执行相同的操作:

...if (dg.Columns[ColumnIndex] is BoundColumn)
 return myReader.GetOrdinal((
 (BoundColumn)dg.Columns[ColumnIndex]).DataField);elseif (dg.Columns[ColumnIndex] is HyperLinkColumn)
 return myReader.GetOrdinal((
 (HyperLinkColumn)dg.Columns[ColumnIndex]).DataTextField);
...

但是,如果使用模板列,或者你不满意这个"默认服务",你可以拥有自己的序号提供程序。 在示例网页中,我使用一个模板列,用户 DataGrid ( SPDataGrid1 ) 中的复选框,显示客户是一个国际( 非美国) 客户。 这是全部 选择 语句:

select CustomerID, CompanyName, ContactName, ContactTitle, Address, 
 City, Country,(case country when'USA'then0else1end) asIntfrom customers

模板列如下所示:

<asp:templatecolumnHeaderText="Int"><ItemTemplate><asp:checkboxid=CheckBox1 Enabled="False"Checked='<%#Convert.ToBoolean(DataBinder.Eval(Container.DataItem, 
 "Int"))%>'Text=""runat="server"></asp:CheckBox></ItemTemplate></asp:TemplateColumn>

为了使这个模板列可以排序,我重写默认的OrdinalProvider 类并在SQL中提供这个列的序号 选择 语句:

publicclass SPDataGrid1_OrdinalProvider : OrdinalProvider
{
 publicoverrideint GetColumnOrdinal(SPDataGrid dg, 
 SqlDataReader myReader, int ColumnIndex)
 {
 //The Int Template columnif (ColumnIndex == 7)
 return7;
 elsereturnbase.GetColumnOrdinal(dg, myReader, ColumnIndex);
 }
}

要做的唯一事情就是告诉 DataGrid 使用这个 OrdinalProvider 而不是默认的一个:

privatevoid Page_Load(object sender, System.EventArgs e)
{
. . .
 SPDataGrid1.myOrdinalProvider = new SPDataGrid1_OrdinalProvider();
. . .
}

分页

DataGridNavigationBar 是从 Panel 类继承的复合控件。 它包含几个标签,文本框和按钮。 你可以使用 adjust/add/remove 元素对它的进行定制。 记得在按钮中添加适当的OnClick 事件处理程序,如我所述。 类没有任何 public 方法,但有两种内部方法从协作 DataGrid 中调用:

internalvoid Initialize(string AttachedTo)internalvoid AdjustNavigationBar(int NumberOfRows, int CurrentPageIndex, 
 int PageCount, int PageSize)

第一种方法"附加"导航栏到 DataGrid,然后调用第二个方法,根据 DataGridCurrentPageIndex 属性启用/禁用导航按钮。

结束语

这里提供的DataGrid 类( 与"护送"类) 为 ASP.NET DataGrid 提供了一种可以重用的机制,可以将排序和分页功能。 这个类只使用从关系数据库引擎( RDBMS ) 中填充的DataGrid 显示内容。 但是,通过修改,你可以构建自己的DataGrid 类,该类可以与任何其他数据源一起工作。 为了给你一些开始,想想使用 DataView.Sort 方法而不是构建 SQL 选择 语句的语句 ORDER BY 就像我在本文中所做的。

快乐编程 !

历史记录

  • April 26,2005 - 初始版本。
  • July 14,2005 - 更新版本 1.1:
    • 为了更好的性能和更清晰的代码,NavigationBarControlIDNavigationBarControl 取代。
    • 引入 SortingMgr 类为 HyperLinkTemplate 列提供排序特性。
    • 创建 ResetInputHiddenValue 方法并调用 inside的SPDataGridOnLoad,以清除 __Cmd__CmdParam ( Bug 修复)。

数据    Datagrid  sort  Paging  
相关文章