王朝网络
分享
 
 
 

一个相当独立的.通用分页控件c#源码四(downmoon收集)

王朝c#·作者佚名  2006-04-14
宽屏版  字体: |||超大  

public class DefaultPagerLayout:ITemplate

{

private ImageButton Next;

private ImageButton First;

private ImageButton Last;

private ImageButton Previous;

private Panel Pager;

public DefaultPagerLayout()

{

Next = new ImageButton();

First = new ImageButton();

Last = new ImageButton();

Previous = new ImageButton();

Pager = new Panel();

Next.ID='Next'; Next.AlternateText='下一页';Next.ImageUrl='play2.gif';

First.ID='First'; First.AlternateText='首页';First.ImageUrl='play2L_dis.gif';

Last.ID = 'Last'; Last.AlternateText ='末页';Last.ImageUrl='play2_dis.gif';

Previous.ID='Previous'; Previous.AlternateText='上一页';Previous.ImageUrl='play2L.gif';

Pager.ID='Pager';

}

public void InstantiateIn(Control control)

{

control.Controls.Clear();

Table table = new Table();

table.BorderWidth = Unit.Pixel(0);

table.CellSpacing= 1;

table.CellPadding =0;

TableRow row = new TableRow();

row.VerticalAlign = VerticalAlign.Top;

table.Rows.Add(row);

TableCell cell = new TableCell();

cell.HorizontalAlign = HorizontalAlign.Right;

cell.VerticalAlign = VerticalAlign.Middle;

cell.Controls.Add(First);

cell.Controls.Add(Previous);

row.Cells.Add(cell);

cell = new TableCell();

cell.HorizontalAlign= HorizontalAlign.Center;

cell.Controls.Add(Pager);

row.Cells.Add(cell);

cell = new TableCell();

cell.VerticalAlign = VerticalAlign.Middle;

cell.Controls.Add(Next);

cell.Controls.Add(Last);

row.Cells.Add(cell);

control.Controls.Add(table);

}

}

DefaultPagerLayout通过编程的方式提供了所有的导航元素,并将它们加入到aspx页面,不过这一次导航元素用标准的HTML表格设置了格式。现在,如果用户没有提供一个表现模板,程序将自动提供一个默认的模板。

[TemplateContainer(typeof(LayoutContainer))]

public ITemplate Layout

{

get{return (_layout == null)? new DefaultPagerLayout():_layout;}

set{_layout =value;}

}

下面再来看看生成各个页面编号的过程。分页控件首先需要确定一些属性值,通过这些属性值来确定要生成多少不同的页面编号。

public int CurrentPage

{

get

{

string cur = (string)ViewState['CurrentPage'];

return (cur == string.Empty || cur ==null)? 1 : int.Parse(cur);

}

set

{

ViewState['CurrentPage'] = value.ToString();}

}

public int PagersToShow

{

get{return _results;}

set{_results = value;}

}

public int ResultsToShow

{

get{return _resultsperpage;}

set{_resultsperpage = value;}

}

CurrentPage保存的实际上是页面编号的ViewState中的当前页面,PagersToShow方法定义的属性允许用户指定要显示多少页面,而ResultsToShow定义的属性则允许用户指定每页要显示多少记录,默认值是10。

NumberofPagersToGenerate返回当前应当生成的页面编号的数量。

private int PagerSequence

{

get

{

return Convert.ToInt32

(Math.Ceiling((double)CurrentPage/(double)PagersToShow));}

}

private int NumberOfPagersToGenerate

{

get{return PagerSequence*PagersToShow;}

}

private int TotalPagesToShow

{

get{return Convert.ToInt32(Math.Ceiling((double)TotalResults/(double)_resultsperpage));}

}

public int TotalResults

{

get{return _builder.Adapter.TotalCount;}

}

TotalPagesToShow方法返回要显示的总页面数量,由用户预设的ResultsToShow属性调整。

虽然ASP.NET定义了一些默认的样式,不过对于分页控件的用户它们可能不是很实用。用户可以通过自定义样式来调整分页控件的外观。

public Style UnSelectedPagerStyle {get {return UnselectedPager;}}

public Style SelectedPagerStyle {get {return SelectedPager;}}

UnSelectedPagerStyle提供了页面编号未选中时所用的样式,而SelectedPagerStyle提供了页面编号被选中时所用的样式。

private void GeneratePagers(WebControl control)

{

control.Controls.Clear();

int pager = (PagerSequence-1)* PagersToShow +1;

for (;pager<=NumberOfPagersToGenerate && pager<=TotalPagesToShow;pager++)

{

LinkButton link = new LinkButton();

link.Text = pager.ToString();

link.ID = pager.ToString();

link.Click += new EventHandler(this.Pager_Click);

if (link.ID.Equals(CurrentPage.ToString()))

link.MergeStyle(SelectedPagerStyle);

else

link.MergeStyle(UnSelectedPagerStyle);

control.Controls.Add(link);

control.Controls.Add(new LiteralControl(' '));

}

}

private void GeneratePagers()

{

GeneratePagers(Holder);

}

GeneratePagers方法动态地创建所有页面编号,页面编号是LinkButton类型的按钮。各个页面编号的标签和ID属性通过循环赋值,同 时,点击事件被绑定到适当的事件句柄。最后,页面编号被加入到一个容器控件——在本例中是一个Panel对象。按钮ID起到了标识哪一个按钮触发点击事件 的作用。下面是事件句柄的定义:

private void Pager_Click(object sender, System.EventArgs e)

{

LinkButton button = (LinkButton) sender;

CurrentPage = int.Parse(button.ID);

RaiseEvent(PageChanged, this,new PageChangedEventArgs(CurrentPage,PagedEventInvoker.Pager));

Update();

}

private void Next_Click(object sender, System.Web.UI.ImageClickEventArgs e)

{

if (CurrentPage<TotalPagesToShow)

CurrentPage++;

RaiseEvent(PageChanged, this,new PageChangedEventArgs(CurrentPage,PagedEventInvoker.Next));

Update();

}

private void Previous_Click(object sender, System.Web.UI.ImageClickEventArgs e)

{

if (CurrentPage > 1)

CurrentPage--;

RaiseEvent(PageChanged, this,new PageChangedEventArgs(CurrentPage,PagedEventInvoker.Previous));

Update();

}

private void First_Click(object sender, System.Web.UI.ImageClickEventArgs e)

{

CurrentPage = 1;

RaiseEvent(PageChanged, this,new PageChangedEventArgs(CurrentPage,PagedEventInvoker.First));

Update();

}

private void Last_Click(object sender, System.Web.UI.ImageClickEventArgs e)

{

CurrentPage = TotalPagesToShow;

RaiseEvent(PageChanged, this,new PageChangedEventArgs(CurrentPage,PagedEventInvoker.Last));

Update();

}

这些事件句柄都相似,它们首先更改分页控件的当前页面,然后刷新绑定的控件。

private void Update()

{

if (!HasParentControlCalledDataBinding) return;

ApplyDataSensitivityRules();

BindParent();

BoundControl.DataBind();

}

首先,分页控件通过调用HasParentControlCalledDataBinding方法检查是否已经初始化了必要的适配器。如果是,则将前面 指出的根据数据显示情况自动调整控件的规则应用到当前的控件,这些规则使得分页控件根据BoundControl中数据的不同情况表现出不同的行为。虽然 这些规则由分页控件内部控制,但必要时可以用[GoF] State模式方便地移出到控件之外。

public bool IsDataSensitive

{

get{return _isdatasensitive;}

set{_isdatasensitive = value;}

}

private bool IsPagerVisible

{

get{return (TotalPagesToShow != 1) && IsDataSensitive;}

}

private bool IsPreviousVisible

{

get

{

return (!IsDataSensitive)? true:

(CurrentPage != 1);

}

}

private bool IsNextVisible

{

get

{

return (!IsDataSensitive)? true:

(CurrentPage != TotalPagesToShow);

}

}

private void ApplyDataSensitivityRules()

{

FirstButton.Visible = IsPreviousVisible;

PreviousButton.Visible = IsPreviousVisible;

LastButton.Visible = IsNextVisible;

NextButton.Visible = IsNextVisible;

if (IsPagerVisible) GeneratePagers();

}

ApplyDataSensitivityRules方法实施预定义的规则,诸如IsPagerVisible、IsPreviousVisible和 IsNextVisible。默认情况下,分页控件将启用这些规则,但用户可以通过设置IsDataSensitive属性来关闭这些规则。

至此为止,分页控件的显示部分基本设计完毕。最后剩下的结束工作是提供几个事件句柄,使得用户能够在各种分页控件事件出现时进行必要的调整。

public delegate void PageDelegate(object sender,PageChangedEventArgs e);

public enum PagedEventInvoker{Next,Previous,First,Last,Pager}

public class PageChangedEventArgs:EventArgs

{

private int newpage;

private Enum invoker;

public PageChangedEventArgs(int newpage):base()

{

this.newpage = newpage;

}

public PageChangedEventArgs(int newpage,PagedEventInvoker invoker)

{

this.newpage = newpage;

this.invoker = invoker;

}

public int NewPage {get{return newpage;}}

public Enum EventInvoker{get{return invoker;}}

}

由于分页控件需要返回自定义的事件参数,所以我们定义了一个专用的PageChangedEventArgs类。 PageChangedEventArgs类返回PagedEventInvoker类型,PagedEventInvoker类型是可能触发事件的控件 的枚举量。为了处理自定义的事件参数,我们定义了一个新的delegate,即PageDelegate。事件按照下面的形式定义:

public event PageDelegate PageChanged;

public event EventHandler DataUpdate;

当事件没有对应的事件监听器时,ASP.NET会抛出一个异常。分页控件定义了下列RaiseEvent方法。

private void RaiseEvent(EventHandler e,object sender)

{

this.RaiseEvent(e,this,null);

}

private void RaiseEvent(EventHandler e,object sender, PageChangedEventArgs args)

{

if(e!=null)

{

e(sender,args);

}

}

private void RaiseEvent(PageDelegate e,object sender)

{

this.RaiseEvent(e,this,null);

}

private void RaiseEvent(PageDelegate e,object sender, PageChangedEventArgs args)

{

if(e!=null)

{

e(sender,args);

}

}

现在事件句柄可以通过调用各个RaiseEvent方法来触发事件了。

四、应用实例

至此为止,分页控件的设计已经全部完成,可以正式使用了。要使用该分页控件,只要把它绑定到一个表现控件即可。

<asp:Repeater ID='repeater' Runat='server'>

<ItemTemplate>

列1:

<%# Convert.ToString(DataBinder.Eval(Container.DataItem,'Column1'))%>

<br>

列2:

<%# Convert.ToString(DataBinder.Eval(Container.DataItem,'Column2'))%>

<br>

列3:

<%# Convert.ToString(DataBinder.Eval(Container.DataItem,'Column3'))%>

<br>

<hr>

</ItemTemplate>

</asp:Repeater>

<cc1:Pager id='pager' ResultsToShow='2' runat='server' BindToControl='repeater'>

<SELECTEDPAGERSTYLE BackColor='Yellow' />

</cc1:Pager>

上面的aspx页面将分页控件绑定到一个Repeater控件,设置每页显示的记录数量为2,选中的页面编号颜色为黄色,使用默认的布局,效果如图一。下面是另一个例子,它将分页控件绑定到一个DataGrid,效果如图二。

<asp:DataGrid ID='Grid' Runat='server'></asp:DataGrid>

<cc1:Pager id='PagerGrid' ResultsToShow='2' runat='server' BindToControl='Grid'>

<SELECTEDPAGERSTYLE BackColor='Red'></SELECTEDPAGERSTYLE>

<LAYOUT>

<asp:ImageButton id='First' Runat='server' imageUrl='play2L_dis.gif' AlternateText='首页'></asp:ImageButton>

<asp:ImageButton id='Previous' Runat='server' imageUrl='play2L.gif' AlternateText='上一页'></asp:ImageButton>

<asp:ImageButton id='Next' Runat='server' imageUrl='play2.gif' AlternateText='下一页'></asp:ImageButton>

<asp:ImageButton id='Last' Runat='server' imageUrl='play2_dis.gif' AlternateText='末页'></asp:ImageButton>

<asp:Panel id='Pager' Runat='server'></asp:Panel>

</LAYOUT>

</cc1:Pager>

测试表明,分页控件并不依赖于特定的表现控件,它可以方便地处理不同的数据源,而且很容易使用,请读者下载本文后面的源代码参见完整的例子。

虽然学习开发自定义Web控件不是一件轻松的事情,但掌握这项技能带来的好处不言而喻,只要稍微增加一些工作量,开发者就可以将普通的Web控件改换成 多用途的通用控件,数十倍地提高工作效率,本文的分页控件只是创建通用控件来满足现有和将来表现需要的其中一个例子而已。

应用实例:

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
>>返回首页<<
推荐阅读
 
 
频道精选
 
静静地坐在废墟上,四周的荒凉一望无际,忽然觉得,凄凉也很美
© 2005- 王朝网络 版权所有