webabcd - 专注于asp.net
ASP.NET
从现在开始 一切都不晚
posts - 152, comments - 4207, trackbacks - 346, articles - 0
博客园
::
首页
::
新随笔
::
联系
::
订阅
::
管理
[翻译]ASP.NET 3.5中的ListView控件和DataPager控件
Posted on 2007-08-13 08:18
webabcd
阅读(8244)
评论(47)
编辑
收藏
网摘
所属分类:
Translation翻译
、
Control控件
原文地址:
http://www.west-wind.com/WebLog/posts/127340.aspx
[译者改后源码下载]
[翻译]ASP.NET 3.5中的ListView控件和DataPager控件
原文发布日期:2007.08.02
作者:
Rick Strahl
翻译:
webabcd
介绍
今天,我花了几个小时的时间研究了一下ASP.NET 3.5中的ListView控件和DataPager控件。 这两个控件是ASP.NET中新增的、非常受欢迎的控件。 ListView控件集成了DataGrid、DataList、Repeater和GridView控件的所有功能。 它可以像Repeater控件那样,让我们在控件内写任何HTML代码。
可以说,ListView就是DataGrid和Repeater的结合体,它既有Repeater控件的开放式模板,又具有DataGrid控件的编辑特性。 这绝对是一个可以引起你兴趣的好东东,因为它给你提供了比DataGird丰富得多的布局手段,同时又具有DataGrid的所有特性。 ListView控件本身并不提供分页功能,但是我们可以通过另一个控件 – DataPager来实现分页的特性。 把分页的特性单独放到另一个控件里,会给我们带来很多好处,比如说可以让别的控件使用它,又比如说我们可以把它放在页面的任何地方。 实质上,DataPager就是一个扩展ListView分页功能的控件。
ListView控件
ListView是用来显示数据的,它的使用类似于Repeater控件。 ListView控件中有n多模板,出示如下:
·LayoutTemplate
·ItemTemplate
·AlternatingItemTemplate
·SelectedItemTemplate
·EmptyItemTemplate
·EmptyDataTemplate
·ItemSeparatorTemplate
·GroupTemplate
·GroupSeparatorTemplate
·EditItemTemplate
·InsertItemTemplate
它有很多的模板。 其中有许多新增的模板,如GroupTemplate和InsertItemTemplate。 现在我们可能还无法了解GroupTemplate是如何工作的(后面会有介绍),但是对于InsertItemTemplate来说,一看就知道它是用于添加记录的(在之前的DataGird中是没有这个模板的)。
继续摸索这个控件后,我发现它可以让你在它的模板内写任何HTML标记或控件,这将给我们带来很大的自由度。
用ListView显示数据
开始,你可以把ListView当作是Repeater来使用,也就是说它是模板驱动型的控件,其中的LayoutTemplate是ListView的一个布局模板。 参考如下示例:
<
asp:ListView
ID
="lvItems"
runat
="server"
DataSourceID
="Data"
ItemContainerID
="layoutTemplate"
DataKeyNames
="Pk"
>
<
Layouttemplate
>
<
div
id
="layoutTemplate"
runat
="server"
/>
</
Layouttemplate
>
<
ItemTemplate
>
<
div
class
="itemdisplay"
>
<
b
>
<%
#
Eval
(
"
Sku
"
)
%>
</
b
><
br
/>
<%
#
Eval
(
"
Abstract
"
)
%>
</
div
>
</
ItemTemplate
>
</
asp:ListView
>
LayoutTemplate用来决定包裹着详细内容的容器的标记。 你可以在布局模板内放置任何控件,不过它必须要是服务端控件(runat=”server”)。 另外,你还需要指定ListView控件的ItemContainerID属性,它用来告知ListView在哪个容器下显示详细内容。 在上面的例子中,LayoutTemplate其实并没有起到什么作用,因为它只是将ListView显示的详细内容放到了一个<div />标记下而已。 但是,我们也可以用它来显示复杂的布局,如<table />。 请看下面的例子,它就是用<table />来做ListView显示的详细内容的容器的,并且它还有一个固定表头的功能。
<
asp:ListView
ID
="lvItemsTable"
runat
="server"
DataSourceID
="Data"
ItemContainerID
="layoutTableTemplate"
DataKeyNames
="Pk"
>
<
LayoutTemplate
>
<
div
class
="blackborder"
style
="overflow-y:auto;height:500px;width:800px;"
>
<
table
cellpadding
="5"
>
<
thead
style
="position:relative;"
>
<
tr
class
="gridheader"
style
="height:30px;"
>
<
th
style
="position:relative"
>
Sku
</
th
><
th
style
="position:relative"
>
Abstract
</
th
>
</
tr
>
</
thead
>
<
tbody
id
="layoutTableTemplate"
runat
="server"
style
="height:470px;overflow:scroll;overflow-x:hidden;"
></
tbody
>
</
table
>
</
div
>
</
LayoutTemplate
>
<
ItemTemplate
>
<
tr
style
="height:0px;"
>
<
td
valign
="top"
>
<%
#
Eval
(
"
Sku
"
)
%>
</
td
>
<
td
valign
="top"
>
<%
#
Eval
(
"
Abstract
"
)
%>
</
td
>
</
tr
>
</
ItemTemplate
>
</
asp:ListView
>
请注意一下上面的布局模板,特别是其中的<TBODY />部分。 ItemTemplate会将其内生成的详细内容插入到<TBODY />之中。
增加分页功能
如果你想为ListView增加分页功能的话,那么就需要使用DataPager控件了。 这个分页控件是一个独立的控件,你可以把它放到页面的任何位置,然后使其联到你的ListView控件就可以完成分页的工作了。 该分页控件所呈现出来的HTML标记为内联(Inline)元素,所以如果你想精确地设置其位置的话,可以参考下面的代码,为其包裹一个<div />标记。
你可以像下面这样设置分页控件,并可以把其放到页面的任何位置。
<
div
class
="blockheader"
style
="padding:10px;text-align: right;"
>
<
asp:DataPager
ID
="Pager"
runat
="server"
PagedControlID
="lvItems"
PageSize
="5"
>
<
Fields
>
<
asp:numericpagerfield
ButtonCount
="10"
NextPageText
="
"
PreviousPageText
="
"
/>
<
asp:nextpreviouspagerfield
FirstPageText
="First"
LastPageText
="Last"
NextPageText
="Next"
PreviousPageText
="Previous"
/>
</
Fields
>
</
asp:DataPager
>
</
div
>
通过上面的代码你会发现,我们可以通过设置DataPager控件的Fields,从而达到手动设置分页布局的目的。 另外还有一个关键点,就是DataPager控件的PagedControlID属性,你需要把它设置为ListView的ID。
当然你也可以把DataPager控件放到布局模板内。
把分页功能作为一个单独的控件分离出来是一个非常好的注意 – 它会让我们有更多的布局和 显示上的自由度。 但是,目前的分页控件还是有其局限性的。 它只能结合ListView控件一起工作 – 如果能用在Repeater或GridView上就更好了。 另外,它也是要依赖于ViewState的。
还有,现在的DataPager控件没有分页事件,也没有SelectedPageIndex属性。
还有一点需要注意的是,ListView没有内置排序功能。
在ListView中添加和编辑数据
ListView通过EditItemTemplate和InsertItemTemplate来提供编辑数据和添加数据的功能。 这个功能的使用非常类似于GridView的编辑特性的使用,只不过它用的都是自定义模板。
<
asp:ListView
ID
="lvItems"
runat
="server"
DataSourceID
="Data"
ItemContainerID
="layoutTemplate"
DataKeyNames
="Pk"
InsertItemPosition
="None"
>
<
Layouttemplate
>
<
div
id
="layoutTemplate"
runat
="server"
/>
</
Layouttemplate
>
<
ItemTemplate
>
<
div
class
="itemdisplay"
>
<
b
>
<%
#
Eval
(
"
Sku
"
)
%>
</
b
><
br
/>
<%
#
Eval
(
"
Abstract
"
)
%>
</
div
>
<
asp:Button
ID
="Button1"
runat
="server"
CommandName
="Edit"
Text
="Edit"
/>
<
asp:Button
ID
="Button2"
runat
="server"
CommandName
="Delete"
Text
="Delete"
/>
</
ItemTemplate
>
<
AlternatingItemTemplate
>
<
div
class
="itemdisplayalternate"
>
<
b
>
<%
#
Eval
(
"
Sku
"
)
%>
</
b
><
br
/>
<%
#
Eval
(
"
Abstract
"
)
%>
</
div
>
<
asp:Button
ID
="Button1"
runat
="server"
CommandName
="Edit"
Text
="Edit"
/>
<
asp:Button
ID
="Button2"
runat
="server"
CommandName
="Delete"
Text
="Delete"
/>
</
AlternatingItemTemplate
>
<
EditItemTemplate
>
<
div
class
="gridalternate"
>
Sku:
<
asp:TextBox
runat
="server"
ID
="txtSku"
Text
='<%#
Bind("Sku") %
>
'>
</
asp:TextBox
>
<
br
/>
Abstract:
<
asp:TextBox
runat
="server"
id
="txtAbstract"
Text
='<%#
Bind("Abstract") %
>
'>
</
asp:TextBox
>
<
br
/>
<
asp:Button
ID
="Button3"
runat
="server"
CommandName
="Update"
Text
="Update"
/>
<
asp:Button
ID
="Button4"
runat
="server"
CommandName
="Cancel"
Text
="Cancel"
/><
br
/>
</
div
>
</
EditItemTemplate
>
<
InsertItemTemplate
>
<
div
style
="background:Yellow"
>
<
asp:TextBox
runat
="server"
ID
="txtSku"
Text
='<%#
Bind("Sku") %
>
'>
</
asp:TextBox
>
<
br
/>
<
asp:TextBox
runat
="server"
id
="txtAbstract"
Text
='<%#
Bind("Abstract") %
>
'>
</
asp:TextBox
>
<
br
/>
</
div
>
<
asp:Button
ID
="Button3"
runat
="server"
CommandName
="Inser"
Text
="Insert"
/>
<
asp:Button
ID
="Button4"
runat
="server"
CommandName
="Cancel"
Text
="Cancel"
/><
br
/>
</
InsertItemTemplate
>
</
asp:ListView
>
在本例中我使用的是SqlDataSource(我比较懒),SqlDataSource中的Insert和Update语句是你必须要提供的。 InsertItemTemplate是ListView中新增的非常受欢迎的模板,我们可以把它的UI设置成与编辑模板相一致。 我们还可以通过InsertItemPosition属性来指定插入模板的位置,它可以是FirstItem、LastItem或None。 一般来说,应该把它设置为None,然后通过某个按钮来设置插入模板的显示位置(FirstItem或LastItem)。示例代码如下:
protected
void
btnAddItem_Click(
object
sender, EventArgs e)
{
this
.lvItems.InsertItemPosition
=
InsertItemPosition.FirstItem;
}
protected
void
lvItems_ItemCommand(
object
sender, ListViewCommandEventArgs e)
{
if
(e.CommandName
==
"
Update
"
)
{
TextBox tb
=
e.Item.FindControl(
"
txtSku
"
)
as
TextBox;
this
.lvItems.InsertItemPosition
=
InsertItemPosition.None;
Response.Write(tb.Text);
}
if
(e.CommandName
==
"
Cancel
"
)
{
this
.lvItems.InsertItemPosition
=
InsertItemPosition.None;
}
}
你可以在OnItemCommand中写上自己的逻辑,使得一旦执行了Update或Cancel命令就设置InsertItemPosition为None。
分组
大概介绍一下,最后生成的HTML代码会先用GroupTemplate分组,然后再以LayoutTemplate做容器包裹起来。
<
Layouttemplate
>
<
div
id
="groupContainer"
runat
="server"
>
</
div
>
</
Layouttemplate
>
<
GroupTemplate
>
<
div
class
="blockheader"
style
="height:23px;padding:7px"
>
Group Header:
</
div
>
<
div
id
="layoutTemplate"
runat
="server"
/>
</
GroupTemplate
>
你可以设置ListView的GroupItemCount属性,来指定每组显示多少条记录。
总结
ListView是ASP.NET中新增的一个非常酷的控件。 在本文中我已经介绍过了,相对于GridView来说它有着更为丰富的布局手段,你可以在它的模板内写任何HTML标记或者控件。 如果你使用过Repeater和GridView的话,那么你将会轻松的上手ListView,不过很明显地,你也将要手写更多的HTML标记。 但是,它也将会给我们带来更多的布局上的自由度,同时也具有编辑、插入等特性。 这就是ASP.NET 3.5给我们带来的非常棒的控件。
Feedback
#1楼
回复
引用
查看
2007-08-13 08:51 by
网魂小兵
功能不错,但是性能肯定会损耗不少!!!
我曾也看过他的一些介绍!
#2楼
[
楼主
]
回复
引用
查看
2007-08-13 09:03 by
webabcd
@网魂小兵
功能和性能不能兼得啊
#3楼
回复
引用
2007-08-13 22:36 by
黑白 [未注册用户]
支持
顺便问一句,这个只有在vs2008里有吗?
#4楼
回复
引用
查看
2007-08-14 06:37 by
金色海洋(jyk)
原来如此,也没有什么呀。居然到了2008 才把分页和显示数据分离出来。
#5楼
[
楼主
]
回复
引用
查看
2007-08-14 07:41 by
webabcd
@黑白
嗯,asp.net 3.5里新增的控件
下一个vs2008玩玩吧
#6楼
[
楼主
]
回复
引用
查看
2007-08-14 07:44 by
webabcd
@金色海洋(jyk)
嗯,其实还是很不错的
#7楼
回复
引用
2007-08-14 19:28 by
ivw [未注册用户]
支持。。。。。
#8楼
回复
引用
2007-08-14 22:57 by
黑白 [未注册用户]
请问webabcd
怎么才能下载到vs2008呢
#9楼
[
楼主
]
回复
引用
查看
2007-08-15 07:48 by
webabcd
@ivw
:)
@黑白
http://msdn2.microsoft.com/en-us/vstudio/aa700831.aspx
http://msdn2.microsoft.com/en-us/express/future/bb421473.aspx
#10楼
回复
引用
2007-08-17 17:40 by
ivw [未注册用户]
请问兄弟,
请问怎样可以氢后面的日期变成前面的数字啊
1186755600 2007-8-10 22:20
1189434000 2007-9-10 22:20
1189520400 2007-9-11 22:20
#11楼
[
楼主
]
回复
引用
查看
2007-08-17 18:50 by
webabcd
@ivw
不知道你的是什么算法、
我推测可能是
分*60+时*60*60+天*24*60*60
以此类推
#12楼
回复
引用
2007-08-17 19:53 by
ivw [未注册用户]
但年份好像不知怎么算出来的。看看这个
1155738000 2006-8-16 22:20
#13楼
回复
引用
2007-08-17 19:55 by
ivw [未注册用户]
这个才对
1157984400 2006-9-11 22:20
#14楼
[
楼主
]
回复
引用
查看
2007-08-17 20:08 by
webabcd
@ivw
嗯,算了一下,猜不出年份是怎么算的
#15楼
回复
引用
2007-08-17 20:13 by
ivw [未注册用户]
前面都可以算出来,而他减一年后想差刚好就是一个平年的秒数31536000,但就是不知道2007这整年是怎么来的
#16楼
[
楼主
]
回复
引用
查看
2007-08-17 20:19 by
webabcd
@webabcd
嗯,是的,我也猜不出
#17楼
回复
引用
2007-08-17 21:07 by
ivw [未注册用户]
会不会这样呢,从2000年开始,而2000年这是一个固定的数,然后加一年就加31536000
#18楼
回复
引用
2007-08-17 21:58 by
ivw [未注册用户]
哈哈,终于算出来了。。还真麻烦啊
#19楼
回复
引用
2007-08-17 22:00 by
ivw [未注册用户]
接着就要返算了。。555555555
#20楼
回复
引用
2007-08-18 09:49 by
ivw [未注册用户]
要还原好像更麻烦啊。。
#21楼
回复
引用
2007-08-19 14:32 by
ivw [未注册用户]
请问兄弟,Treeview怎样可以改变子叶的排列方式啊?一般它是向下排列的,怎么可以改变成一行三个这样排啊?
#22楼
[
楼主
]
回复
引用
查看
2007-08-20 07:36 by
webabcd
@ivw
正算的算法定了,反算就很容易了
呵,TreeView没有现成的属性让你这样做啊
#23楼
回复
引用
2007-12-15 18:19 by
陆建华 [未注册用户]
您好,我最近认真的看了你的博客,你可以提供给我一写关于.NET3.5方面的资料吗?发到我的邮箱,谢谢~~~
#24楼
[
楼主
]
回复
引用
查看
2007-12-17 00:37 by
webabcd
@陆建华
:)
我的资料就是MSDN啊
其实这也是绝大部分参考书的资料
#25楼
回复
引用
查看
2008-01-23 16:32 by
tianyamoon
当使用代码对ListView进行数据绑定的时候如何来使用datapager进行分页?
例如:
private void BindListView()
{
this.ListView1.DataSourceID = "";
this.ListView1.DataSource = db.Merchandises;this.ListView1.DataBind();
}
我在ListView中添加了DataPager但是在实现的页面中需要点两次下一页才能翻一页,而且无法向前翻页,不知其原因。
如果您能正常实现的话,请给个例子,谢谢。
#26楼
[
楼主
]
回复
引用
查看
2008-01-23 19:16 by
webabcd
@tianyamoon
你可以下载本文中提供的我修改后的源码,有例子
在vs2008正式版测试通过
#27楼
回复
引用
查看
2008-01-23 19:43 by
tianyamoon
@webabcd
首先谢谢您的回复
但是代码我之前就看过了,不过你的代码里是直接使用的LinqDataSource来进行的数据绑定,而不是像我上面那样的绑定。
你可以试试,我那种绑定方式我的分页怎么也不能正常工作,查了好多资料都没找到解决办法。
#28楼
[
楼主
]
回复
引用
查看
2008-01-24 08:27 by
webabcd
@tianyamoon
自动实现分页功能是需要结合数据源控件使用的
不习惯用LinqDataSource的话可以用ObjectDataSource
#29楼
回复
引用
查看
2008-01-24 09:02 by
tianyamoon
@webabcd
不是习惯不习惯的问题,是有些时候的数据源你必须在代码里自定义一下。
比如说,如果不可以自定数据源的话,Linq语法就没什么意义了。
使用LinqDataSource生成的sql都是相当简单的。
难道说DataPager真的是鸡肋?
#30楼
[
楼主
]
回复
引用
查看
2008-01-24 11:28 by
webabcd
@tianyamoon
可以用ObjectDataSource
我觉得LINQ套原来的3层开发的话,与数据库打交道的LINQ表达式都要放在数据层,业务层里还是写核心逻辑,然后用ObjectDataSource调业务层
我觉得DataPager还是挺方便的
#31楼
回复
引用
查看
2008-01-24 17:38 by
tianyamoon
@webabcd
ObjectDataSource不是一样破坏了三层架构么?
#32楼
[
楼主
]
回复
引用
查看
2008-01-25 08:12 by
webabcd
@tianyamoon
ObjectDataSource不会破坏三层架构
应该说它相当于数据展现和业务逻辑之间的一个桥梁吧
#33楼
回复
引用
查看
2008-01-25 09:14 by
tianyamoon
@webabcd
我觉得不能这么理解吧,ObjectDataSource的使用,使得我们直接在ASPX文件中就包含了SQL语句。业务数据与界面的耦合度太高了。
比如说我有这么个需求,页面上有两个商品列表,分别是最新TOP10,最热TOP10,我们正确的做法应该是使用userControl吧,因为他们的界面显示是一样的。但是如果使用了ObjectDataSource,我们怎么来定义这个userControl呢?
#34楼
[
楼主
]
回复
引用
查看
2008-01-25 12:11 by
webabcd
@tianyamoon
你说的是SqlDataSource
我说的是ObjectDataSource
如果用3层开发的话,就让ObjectDataSource调用你业务层的方法
ObjectDataSource中不可能出现sql语句的
#35楼
回复
引用
2008-03-03 15:50 by
温编辑 [未注册用户]
各位高手好,我是国内知名出版社的编辑,有asp.net的选题要写,请问你有没有合作意向呢,有的话,请来信吧(wcypublish#gmail.com),谢谢。
#36楼
[
楼主
]
回复
引用
查看
2008-03-03 18:44 by
webabcd
@温编辑
:)
最近很忙啊,没时间啊
#37楼
回复
引用
查看
2008-03-30 17:49 by
堕落的卖猪贩
@tianyamoon
兄弟啊,我也是这个问题。指定datatable或reader给listview。翻页杂都不正常工作,要不是翻到第一页就没数据了。点上一页下一页翻起也有问题。
我绑定的代码
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
this.BindList();
// Pager1.
}
}
private void BindList()
{
//DataTable dt = (new BLL.Department()).GetDataTable("*", "", "_DepartmentId", this.DataPager1.StartRowIndex, this.DataPager1.PageSize);
DataTable dt = (new BLL.Department()).GetDataTable("*", "", "_DepartmentId");
this.ListView1.DataSource = dt;
this.ListView1.DataBind();
this.Label1.Text = this.DataPager1.StartRowIndex + "|" + this.DataPager1.PageSize;
}
protected void ListView1_PagePropertiesChanged1(object sender, EventArgs e)
{
BindList();
}
#38楼
[
楼主
]
回复
引用
查看
2008-03-31 08:28 by
webabcd
@堕落的卖猪贩
用
DataPager
的
SetPageProperties
方法
#39楼
回复
引用
查看
2008-04-24 15:13 by
北漂浪子
最近比较闲,经常看你文章的,写的真好
原打算抓紧时间把你的文章都看一遍
可是5.1过后又要开始做项目了,就没有太多的时间学习啦
-------------------------------------------------
冒昧的问一下,你的英语水平是不是很高,
应该具备最基本的听说读写吧?
我英语学的不好,导致看英文文章很吃力
所以在新技术上老是落后别人半步
不知道有没有好的意见或建议
帮小弟弥补一下英语上的