惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

V
Visual Studio Blog
Engineering at Meta
Engineering at Meta
月光博客
月光博客
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
T
Tailwind CSS Blog
博客园 - Franky
The GitHub Blog
The GitHub Blog
大猫的无限游戏
大猫的无限游戏
The Cloudflare Blog
B
Blog RSS Feed
云风的 BLOG
云风的 BLOG
小众软件
小众软件
罗磊的独立博客
Microsoft Azure Blog
Microsoft Azure Blog
I
InfoQ
美团技术团队
H
Hackread – Cybersecurity News, Data Breaches, AI and More
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
V
V2EX
C
Check Point Blog
WordPress大学
WordPress大学
博客园 - 【当耐特】
博客园 - 司徒正美
D
Docker

博客园 - javalong

VS2005 中通过MasterPage来更方便实现网站模板替换 .Net程序如何防止被注入(整站通用) 不走寻常路 设计ASP.NET应用程序的七大绝招 进制转换(一) 关于ISA2004内网卡网线拔插造成ISA代理失效问题的一种解决方法(下列错误而失败:0x80072 关于三层结构的一点使用心得与开发建议 さくら~歌詞 いきものがかり SAKURA 歌词 修改数据库逻辑名 Windows 2003 R2 一些SN map blog - javalong - 博客园 VB.Net to C# Converter 1.51 图书馆 2006年宜结婚嫁娶黄道吉日通用表 VS2005 发布网站 真的好麻烦!!! 关于URL重写使用正则表达式的一些问题! 使用 ASP.NET 2.0 ObjectDataSource 控件 12月16日参加了传说中的微软新产品发布会!----广州 工厂的资料 数据访问
SimplePager
javalong · 2005-11-08 · via 博客园 - javalong

SimplePager是继承自Repeater的一个自定义控件,在整个站中应用很广,下面通过Category.aspx这个页面具体的研究研究:)
先来看Category.aspx.cs,很奇怪吧,怎么没有和Load事件相关的方法呢?只有一个控制分页的PageChanged,而这个分页方法也有问题,每次都是获得缓存里的数据,然后改变的只CurrentPageIndex属性而已,并且该方法接受的参数竟然是DataGridPageChangedEventArgs,真晕,这个控件是一个Repeater嘛……
下面就让我们打开SimplePager.cs来看个究竟吧~~(两天的感冒刚好,目前精神百倍中……),其实看这个的时候最好是用.NET Reflector来查看,这样比较容易好辨认(我现在的电脑就把打开dll文件的默认程序设成了.NET Reflector)。
先来看第一个问题,在具体的页面中没有Load事件,那肯定是在控件的内部做了手脚

override protected void OnLoad(EventArgs e) {
if (Visible) {
string page = Context.Request[KEY_PAGE];
int index = (page != null) ? int.Parse(page) : 0;
SetPage(index);
}
}
当Load事件发生时就调用SetPage方法
public void SetPage(int index) {
//对DataGridPageChangedEventArgs有疑惑的可以看文章的最后
OnPageIndexChanged(new DataGridPageChangedEventArgs(null, index));
}
然后是OnPageIndexChanged
virtual protected void OnPageIndexChanged(DataGridPageChangedEventArgs e) {
if (PageIndexChanged != null)
PageIndexChanged(this, e);
}
PageIndexChanged是一个事件,使用了DataGridPageChangedEventHandler作为它的委托
public event DataGridPageChangedEventHandler PageIndexChanged;

这样就不难理解了,PageChanged就是在页面加载时的“Page_Load”方法,并且还是页数改变时相应的处理方法。换句话说,每次进入该页,程序都当成页数改变事件来处理。
从上面我们可以看到一个问题,即在这三个连续的方法中页数的传递都是通过
string page = Context.Request[KEY_PAGE];这里获得的值来进行的,好象CurrentPageIndex属性根本就没有用……
CurrentPageIndex的作用主要体现在分页方法这里
override protected void OnDataBinding(EventArgs e) {

//Work out which items we want to render to the page
int start = CurrentPageIndex * pageSize;
int size = Math.Min(pageSize, ItemCount - start);

IList page = new ArrayList();

//Add the relevant items from the datasource
for (int i = 0; i < size; i++)
page.Add(dataSource[start + i]);

//set the base objects datasource
base.DataSource = page; 
base.OnDataBinding(e);

}

OnDataBinding是当服务器控件绑定到数据源时发生的DataBinding事件的处理方法。在这里有机会对数据源进行处理。而这里的确就是对数据源进行了处理,取到当前页的数据并把他们作为新的数据源赋给控件。
for (int i = 0; i < size; i++)
page.Add(dataSource[start + i]);
因为dataSource是实现了IList接口的数据,所以可以这样用索引器来操作数据,再往里面看,这些数据是什么呢?好象以前讨论过这个,数据源实际是一个ArrayList,里面放的是ProductInfo实体。
看到这里,或许你和我一样,会有这样的疑惑,既然在Load阶段就接收到了一个页数,为什么在这里还要另外的用一个,直接用一个不可以吗?我在这里的看法是,这样可以使程序的可读性更高,并且使控件的用户接口更加友好。
或者,那个变量根本就传不到OnDataBinding方法里面?这个我没有调试过,感兴趣的可以试试。
除了这里,Render方法也用CurrentPageIndex来实现上一页和下一页连接的显示。
顺便说一下ViewStatePager,这个是SimplePager的子类,主要的区别是该控件识别页数时使用了ViewState来完成,这样不至于和同一页面上的其他需要分页的控件(比如SimplePager)冲突。
最后说一个小发现
public DataGridPageChangedEventArgs(object commandSource, int newPageIndex)
{
this.commandSource = commandSource;
this.newPageIndex = newPageIndex;
}
这是通过.NET Reflector得到的DataGridPageChangedEventArgs的构造函数
public int NewPageIndex
{
get
{
return this.newPageIndex;
}
}
这是通过.NET Reflector得到的DataGridPageChangedEventArgs的NewPageIndex属性的定义。