知识大全 一个相当独立的通用分页控件c#源码

Posted

篇首语:一个不想蹚过小河的人,自然不想远涉重洋。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 一个相当独立的通用分页控件c#源码相关的知识,希望对你有一定的参考价值。

  通用ASP NET数据分页控件  对于几乎所有的数据表现Web应用来说 组织好数据的显示方式 避免给用户带来混乱的感觉就是最主 要的目标之一 每个页面显示 条记录当然是可以接受的 但每页显示 条记录就很容易给用户带来不便了 将数据分成多个页面显示 即对数据进行分 页 是解决此类问题的最常见的办法   一 慨述   ASP NET本身只提供了一个支持数据分页的控件 即 DataGrid分页控件 不过它比较适合Intranet环境使用 对于Internet环境来说 DataGrid分页控件提供的功能似乎不足以构造 出灵活的Web应用 其中一个原因是 DataGrid控件对Web设计者放置分页控件的位置和分页控件的外观都有限制 例如 DataGrid控件不允 许垂直放置分页控件 另一个能够发挥分页技术优势的控件是Repeater Web开发者可以利用Repeater控件快速配置数据的显示方式 但分页功 能却需要开发者自己实现 数据源在不断地变化 数据表现方式也千差万别 如果针对这些不断变动的条件分别定制分页控件 显然太浪费时间了 构造一个不限于 特定表现控件的通用分页控件将极大地有利于节省时间   一个优秀的通用数据控件不仅提供常规的分页功能 而且还要能够   ⑴ 提供 首页 上一页 下一页 末页 分页导航按钮    ⑵ 根据数据显示情况调整自身的状态 即具有数据敏感性 如果分页控件被设置成每页显示 个记录 但实际上只有 个记录 那么分页控件不应该显示出来 在数 据分成多页显示的情况下 第一个页面的 首页 上一页 按钮不应显示出来 最后一个页面的 下一页 末页 按钮也不应该显示出来   ⑶ 不能依赖于特定的数据显示控件   ⑷ 具有适应各种现有 将有数据源的能力   ⑸ 应当能够方便地配置显示方式 轻松地集成到各种应用之中   ⑹ 当分页就绪时 提醒其他控件   ⑺ 即使是缺乏经验的Web设计者 也要能够毫无困难地使用   ⑻ 提供有关分页信息的属性数据   目前市场上已经有一些提供上述功能的商业性控件 不过都价格不菲 对于许多开发者来说 自己构造一个通用的分页控件是最理想的选择   图一显示了本文通用分页控件的运行界面 其中用于显示的控件是一个Repeater控件 分页控件由两类部件构成 四个导航按钮 一组页面编号链接 用户可以方便地改换显示控件 改变分页控件本身的外观 例如 在图一中 和分页控件协作的显示控件可发换成一个DataGrid控件 页面编号链接和四个导航按钮分两行显示 ASP NET 支持创建定制Web控件的三种方式 用户控件 复合控件 自定义控件 第三种控件即自定义控件的名称很容易引起误解 实际上 所有这三种控件都应该算是自 定义控件 复合控件和微软所谓的自定义控件的不同之处在于 前者要用到CreateChildControls()方法 CreateChildControls()方法允许控件根据某些事件重新绘制自身 对于本文的通用分页器 我们将使用复合控件   下面的UML序列图概括了通用分页控件的一般机制 虽然我们的目标是让通用分页控件不依赖于表现数据的控件 但很显然 总得有某种方法让分页控件访问数据 每一个从Control类继承的控件都提供一个 DataBinding事件 我们把分页器本身注册成DataBinding事件的监听器 分页器就可以获知数据的情况并修改数据 由于所有从 Control类继承的控件都有这个DataBinding事件 所以分页器控件达到了不依赖于特定数据表现控件的目标——换句话说 分页器控件可以绑定 到所有从Control类派生的控件 即它能够绑定到几乎所有的Web控件

  二 核心功能   当表现控件触发DataBinding事件 分页控件就可以获取DataSource属性 遗憾的是 微软没有提供所 有数据绑定类实现的接口 诸如IdataSourceProvider之类 而且并非所有从Control或WebControl类继承的控件都有一个 DataSource属性 因此向上定型成Control类没有意义 唯一可行的办法是通过Reflection API直接操作DataSoruce属性 在讨论事件句柄方法之前 应该指出的是 为了注册事件句柄 首先必须获得一个表现控件的引用 分页控件显露了一 个简单的字符串属性BindToControl

public string BindToControl get if (_bindcontrol == null)throw new NullReferenceException( 在使用分页控件之前 请先通过设置BindToControl属性绑定到一个控件 );return _bindcontrol;set _bindcontrol=value; 

  这个方法非常重要 所以最好能够抛出一个含义更明确的信息 而不是抛出标准的NullReferenceException异常 在分页控件的 OnInit方法中 我们解析了对表现控件的引用 本例应当用OnInit事件句柄(而不是构造函数)来确保JIT编译的aspx页面已经设置了 BindToControl

protected override void OnInit(EventArgs e) _boundcontrol = Parent FindControl(BindToControl);BoundControl DataBinding += new EventHandler(BoundControl_DataBound);base OnInit(E);  

  搜索表现控件的操作通过搜索分页控件的Parent控件完成 在这里 Parent就是页面本身 按照这种方式使用Parent比较危险 举例来说 如 果分页控件嵌入到了另一个控件之中 例如嵌入到了Table控件之中 则Parent引用实际上将是一个对Table控件的引用 由于 FindControl方法只搜索当前的控件集合 除非表现控件就在该集合之中 否则不可能搜索到 一种比较安全的方法是递归地搜索各个控件集合 直至找 到目标控件为止   找到BoundControl之后 我们将分页控件注册成为DataBinding事件的监听器 由于分页控件要操作数 据源 所以该事件句柄应当是调用链中的最后一个 这一点很重要 不过 只要表现控件在OnInit事件句柄中注册DataBinding的事件句柄(默认 行为) 分页控件操作数据源时就不会出现问题   DataBound事件句柄负责获取表现控件的DataSource属性

private void BoundControl_DataBound(object sender System EventArgs e) if (HasParentControlCalledDataBinding) return;Type type = sender GetType();_datasource = type GetProperty( DataSource );if (_datasource == null)throw new NotSupportedException( 分页控件要求表现控件必需包含一个DataSource );object data = _datasource GetGetMethod() Invoke(sender null);_builder = Adapters[data GetType()];if (_builder == null)throw new NullReferenceException( 没有安装适当的适配器来处理下面的数据源类型 +data GetType());_builder Source = data;ApplyDataSensitivityRules();BindParent();RaiseEvent(DataUpdate this); 

  在DataBound中 我们尝试通过Reflection API获得DataSource属性 然后返回实际数据源的一个引用 现在虽然已经获知了数据源 但分页控件还必须知道如何操作该数据源 为了让分页控件 不依赖于特定的表现控件 问题复杂了很多 不过 如果让分页控件依赖于特定的数据源 那就背离了设计一个灵活的分页控件的目标 我们要通过一个接插式的体 系结构来确保分页控件能够处理各种数据源 无论是 NET提供的数据源 还是自定义的数据源   为了提供一个健壮的 可伸缩的接插式体系结构 我们将利用[GoF] Builder模式构造出一个解决方案 IDataSourceAdapter接口定义了分页控件操作数据所需的最基本的元素 相当于 插头

publicinterface IDataSourceAdapter int TotalCount get;object GetPagedData(int start int end); 

  TotalCount属性返回在处理数据之前数据源所包含元素的总数 而GetPagedData方法返回原始数据的一个子集 例如 假设数据源是一个 包含 个元素的数组 分页控件将数据显示成每页 个元素 则第一页的元素子集是数组元素 第二页的元素子集是数组元素 DataViewAdapter提供了一个DataView类型的插头

internal class DataViewAdapter:IDataSourceAdapter private DataView _view;internal DataViewAdapter(DataView view) _view = view;public int TotalCount get return (_view == null) ?   : _view Table Rows Count;public object GetPagedData(int start  int end) DataTable table = _view Table Clone();for (int i = start;i<=end && i<= TotalCount;i++) table ImportRow(_view[i ] Row);return table; 

  DataViewAdapter实现了IDataSourceAdapter的GetPagedData方法 该GetPagedData克隆原始的 DataTable 将原始DataTable中的数据导入到新的DataTable 该类的可见性有意地设置成internal 目的是为了向Web开 发者隐藏实现细节 进而通过Builder类提供一个更简单的接口

public abstract class AdapterBuilder private object _source;private void CheckForNull() if (_source == null) throw new NullReferenceException( 必须提供一个合法的数据源 );public virtual object Source get CheckForNull();return _source;set _source = value;CheckForNull();public abstract IDataSourceAdapter Adapter get;

  AdapterBuilder抽象类为IdataSourceAdapter类型提供了一个更容易管理的接口 由于提高了抽象程度 我们不必再直接使用 IdataSourceAdapter 同时AdapterBuilder还提供了在分页数据之前执行预处理的指令 另外 该Builder还使得实际的 实现类 例如DataViewAdapter 对分页控件的用户透明

public class DataTableAdapterBuilder:AdapterBuilder private DataViewAdapter _adapter;private DataViewAdapter ViewAdapter get if (_adapter == null) DataTable table = (DataTable)Source;_adapter = new DataViewAdapter(table DefaultView);return _adapter;public override IDataSourceAdapter Adapter get return ViewAdapter;public class DataViewAdapterBuilder:AdapterBuilder private DataViewAdapter _adapter;private DataViewAdapter ViewAdapter get  // 延迟实例化if (_adapter == null) _adapter = new DataViewAdapter((DataView)Source);return _adapter;public override IDataSourceAdapter Adapter get return ViewAdapter; cha138/Article/program/ASP/201311/21745

相关参考

知识大全 一个ASP.Net的DataGrid分页控件

一个ASP.Net的DataGrid分页控件  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  写的

知识大全 Struts2分页实现源码

Struts2分页实现源码  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  &

知识大全 一个通用的JSP分页类,具有显示多组页码功能

一个通用的JSP分页类,具有显示多组页码功能  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  最近

知识大全 JS分页控件 可用于无刷新分页

JS分页控件可用于无刷新分页  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!今天无意看到了这个分页控

知识大全 PageNavigator控件实现客户端分页

PageNavigator控件实现客户端分页  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  在这

知识大全 ASP.NET MVC分页控件的实现

ASP.NETMVC分页控件的实现  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  需求及模拟代码

知识大全 myPage分页控件 v2.0.0.2版本

myPage分页控件v2.0.0.2版本  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  v的功能

知识大全 Asp.Net 可定制分页用户控件

Asp.Net可定制分页用户控件  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  介绍借助AspN

知识大全 用AspNetPager控件最详细的分页实现方法

用AspNetPager控件最详细的分页实现方法  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  

知识大全 实现DataList和Repeater控件的分页显示

实现DataList和Repeater控件的分页显示  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!