ASP.NET数据绑定控件

时间:2022-07-20 15:37:14
数据绑定控件简介

数据绑定分为:数据源 和 数据绑定控件 两部分,数据绑定控件通过数据源来获得数据,通过数据源来
隔离数据提供者和数据使用者,数据源有:
SqlDataSource,AccessDataSource,ObjectDataSource,LinqDataSource,XmlDataSource 等
大部分不会直连接数据库,所以SqlDataSource,AccessDataSource不会使用
ObjectDataSource 是WEB开发中应用最广的数据源,也能很容易的进行数据库切换
数据绑定控件有:列表数据绑定控件(DropDownList,RadioButtonList,ListBox,CheckBoxList等)
与 复杂控件(ListView,Repeater,GridView,DetailsView,FormView,DataList,DataGrid等)
Repeater是最轻量级的组件,在前台用的最多,ListView是.NET3.5中新增的控件,
它是 GridView,DetailsView,FormView,Repeater等这些控件的大统一者,那些控件的优点它都有

ObjectDataSource

ObjectDataSource 用来将一个类做为数据源,TypeName属性为数据源类的全名,
有DeleteMethod,InsertMethod,SelectMethod,UpdateMethod等几个属性,分别为类中删除,插入,查询,更新数据的方法名
这些方法可能有参数,参数的值是通过DeleteParameters,UpdateParameters,InserParameters等嵌套设置

手工编写ObjectDataSource太麻烦,使用界面来完成,将ObjectDataSource拖放到界面上,在右上角选择
"配置数据源"即可进行配置,数据源类一般用 数据集 就可以,生成完后,在“配置数据源”中就能看到了

GridView控件

选择
DataKeyNames属性
DataKeys属性
取选中行的数据
取DataKey
单一Key
复合Key
取非Key列
默认方法:Cells[0].Text
使用模板里的控件(复杂列)---在”模板里讲”

---- 处理事件

RowCommand
在 GridView 控件中单击某个按钮时发生。此事件通常用于在该控件中单击某个按钮时执行某项任务。

RowDataBound
在 GridView 控件中的某个行被绑定到一个数据记录时发生。此事件通常用于在某个行被绑定到数据时修改该行的内容。

RowCreated
在 GridView 控件中创建新行时发生。此事件通常用于在创建某个行时修改该行的布局或外观。

DataBound
此事件继承自 BaseDataBoundControl 控件,在 GridView 控件完成到数据源的绑定后发生。

------上面是常用的

PageIndexChanging
在单击页导航按钮时发生,但在 GridView 控件执行分页操作之前。此事件通常用于取消分页操作。

PageIndexChanged
在单击页导航按钮时发生,但在 GridView 控件执行分页操作之后。此事件通常用于在用户定位到该控件中不同的页之后需要执行某项任务时。

SelectedIndexChanging
在单击 GridView 控件内某一行的 Select 按钮(其 CommandName 属性设置为“Select”的按钮)时发生,但在 GridView 控件执行选择操作之前。此事件通常用于取消选择操作。

SelectedIndexChanged
在单击 GridView 控件内某一行的 Select 按钮时发生,但在 GridView 控件执行选择操作之后。此事件通常用于在选择了该控件中的某行后执行某项任务。

Sorting
在单击某个用于对列进行排序的超链接时发生,但在 GridView 控件执行排序操作之前。此事件通常用于取消排序操作或执行自定义的排序例程。

Sorted
在单击某个用于对列进行排序的超链接时发生,但在 GridView 控件执行排序操作之后。此事件通常用于在用户单击对列进行排序的超链接之后执行某项任务。

RowDeleting
在单击 GridView 控件内某一行的 Delete 按钮(其 CommandName 属性设置为“Delete”的按钮)时发生,但在GridView 控件从数据源删除记录之前。此事件通常用于取消删除操作。

RowDeleted
在单击 GridView 控件内某一行的 Delete 按钮时发生,但在 GridView 控件从数据源删除记录之后。此事件通常用于检查删除操作的结果。

RowEditing
在单击 GridView 控件内某一行的 Edit 按钮(其 CommandName 属性设置为“Edit”的按钮)时发生,但在 GridView 控件进入编辑模式之前。此事件通常用于取消编辑操作。

RowCancelingEdit
在单击 GridView 控件内某一行的 Cancel 按钮(其 CommandName 属性设置为“Cancel”的按钮)时发生,但在GridView 控件退出编辑模式之前。此事件通常用于停止取消操作。

RowUpdating
在单击 GridView 控件内某一行的 Update 按钮(其 CommandName 属性设置为“Update”的按钮)时发生,但在GridView 控件更新记录之前。此事件通常用于取消更新操作。

RowUpdated
在单击 GridView 控件内某一行的 Update 按钮时发生,但在 GridView 控件更新记录之后。此事件通常用来检查更新操作的结果。

------- 批量更新 -------
数据操作用的是 强类型DataSet

protected void btnUp_Click(object sender, EventArgs e)
{
var da = new NewsDataSetTableAdapters.categoryTableAdapter();
foreach (GridViewRow row in this.GridView1.Rows)
{
if (row.RowType == DataControlRowType.DataRow)
{
CheckBox ck = row.FindControl("ckSel") as CheckBox;
if (ck.Checked)
{
var cateID = this.GridView1.DataKeys[row.RowIndex].Value;
var cateName = (row.FindControl("txtName") as TextBox).Text; da.Update(cateName, int.Parse(cateID.ToString()));
}
}
}
}

------- 批量删除 -------
和上面的一样

    var cateID = this.GridView1.DataKeys[row.RowIndex].Value;
da.Delete(int.Parse(cateID.ToString()));
Repeate控件

Repeate(foreach)用于对绑定数据源中的数据进行遍历显示,每条数据以什么格式是
由Repeate的<ItemTemplate>来决定,需手动编写
<%#Eval("Name")%>表示在这个位置显示当前行的Name属性,注意 调用Eval,Bind数据绑定方法时要用#
因为Eval就是将属性显示到指定的位置,因此可以显示到文本框中
<ItemTemplate>姓名:<input type="text" value='<%#Eval("Name")%>'/></ItempTemplate>
注意 不要写成 value="<%#Eval('Name')%>" 因为<%%>中的是C#代码,"是字符,而不是字符串
还可以用在服务器控件中<asp:TextBox Text='<%#Eval("Name")%>' runat="server"></asp:TextBox>
注意!:如果是服务端控件那么在 <%#Eval('PicPath')%> 的前面不能加任何东西,不然会将<符编译成&lt;
如果要解决可以这样:建一个转换URL的方法,然后在aspx里面调用,如下:

//新建方法
protected string FormatImgURL(object url) //因为Eval()返回值是 object,所以用此类型
{
return ResolveClientUrl("~/images/+url");
}
//调用
<%#FormatImgURL(Eval("PicPath"))%>

Repeate 其它模板

1.<AlternatingItemTemplate> 设置隔行的不同显示风格,设置后,奇数行用<ItemTemplate>模板,偶数行用<AlternatingItemTemplate>模板

<AlternatingItemTemplate>

  <asp:TextBox BackColor="Red" ID="TextBox2" Text='<%#Eval("Name")%>' runat = "server" />

</AlternatingItemTemplate>

设置隔行变色是为了防止数据太多看串行

2.HeaderTemplate,FotterTemplate: 头部,尾部的模板,分别显示在所有数据的前面和后面

3.SeparatorTemplate: 两项数据之间的分隔符,比如换行符

如下:

<asp:Repeater ID="Repeater1" runat="server" DataSourceID="ObjectDataSource1">
<HeaderTemplate><div style="background-color:Aqua;width:200px;">会员管理系统<br /></div></HeaderTemplate>
<ItemTemplate>主键:<%#Eval("Id") %>姓名:<%#Eval("username") %> <br /></ItemTemplate>
<AlternatingItemTemplate><div style="color:Red">主键:<%#Eval("Id") %>姓名:<%#Eval("username") %> <br /></div></AlternatingItemTemplate>
<FooterTemplate><div style="background-color:Aqua;width:200px;">作者:小高</div></FooterTemplate>
<SeparatorTemplate><hr width="200" align="left"/></SeparatorTemplate>
</asp:Repeater>

ItemDataBound 事件
在项被数据绑定后激发,绑定某行数据后激发
对于每行数据显示的时候都会调用ItemDataBound 事件,在这个事件中可以对当前行进行处理,主要成员:
1. e.Item.ItemType 为当前行的类型,Item为ItemTemplate行,AlternatingItem为AlternatingItemTemplate行,还有Header,Footer等取值
2. e.Item.ItemIndex 当前行的序号
3. e.Item.DataItem 当前行绑定的对象

如果要在ItemDataBound 事件中对ItemTemplate模板中的控件做处理,则必须使用runat=server的控件
为控件设置ID,然后用 FindControl根据ID来取得控件

案例:将年龄大于30的行的颜色变成红色,大于40更改背景颜色
//ItemDataBound事件
DataRowView rowView = (DataRowView)e.Item.DataItem; //得到这行的值
var userRow = (TestObject.DataSetUser.T_User)rowView.Row; //转换成强类型DataSet
if (userRow.Age > ) //当年龄大于 30
{
TextBox txtAge = (TextBox)e.Item.FindControl("txtAge"); //获得模板中的控件
txtAge.BackColor = Color.Red; //设置背景颜色
} if (userRow.Age > ) //当年龄大于40
{
HtmlGenericControl spnRow = (HtmlGenericControl)e.Item.FindControl("spanRow"); //获得整行Span的ID
spanRow.Attributes["class"] = "warning"; //设定定义好的样式
}
ItemCommand(行处理命令)

在 DataList 中生成事件时激发,当用户点击按钮后激发
可以在模板中放置Button控件,模板中的按钮一般不写OnClick事件,而是响应Repeater的ItemDataBound事件
为Button控件设定CommandName,CommandArgument属性,然后在ItemDataBound事件读取e的CommandName,
CommandArgument属性就可以获得发生事件的命令和参数了,如果对数据进行操作,则需要 Repeater1.DataBind()
来重新绑定,从数据库中刷新最新的数据

案例: 涨一岁,给被点击的行的年龄增加1

//Repeater控件设置
<ItemTemplate>姓名:<%#Eval("username") %> 年龄:'<%#Eval("age") %>'
<asp:Button runat="server" Text="加一岁" CommandName="inc"
CommandArgument='<%#Eval("id") %>' /><br /></ItemTemplate>
//增加一个SQL更新语句,名为 IncAgeById()
// update T_Person set age=age+1 where id=@id //ItemCommand事件设置
protected void Repeater1_ItemCommand(object source, RepeaterCommandEventArgs e)
{
if (e.CommandName == "inc")
{
int id = int.Parse(e.CommandArgument.ToString()); //获得当前行的ID值
T_personTableAdapter adapter = new T_personTableAdapter(); //创建 adapter
adapter.IncAgeById(id); //使用自定义SQL进行更新,按当前ID来加一
this.Repeater1.DataBind(); //数据再次绑定,实现网页与数据库同步
}
}

案例2:人员管理程序,增加[禁用]当前行按钮,点击[禁用]将状态设置为 禁用 ,显示为红色,禁用后
显示为[启用],点击[启用]后将颜色去除,显示为[禁用],状态显示为启用

1.先增加两个SQL语句,用于更改当前用户的状态
update T_User set Status = '禁用' where id = @id //方法名为 DisableById
update T_User set Status = '启用' where id = @id //方法名为 EnableById

2.Repeater配置

<HeaderTemplate><table><tr class="head"><td>用户</td><td>状态</td><td>操作</td></tr></HeaderTemplate>
<ItemTemplate><tr id="trRow" runat="server">
<td><%#Eval("UserName") %></td><td><%#Eval("Status") %></td>
<td><asp:Button runat="server" ID="Enabled" Text="启用" OnClientClick="return confirm('你确认启用该用户?')"
CommandName="Enabled" CommandArgument='<%#Eval("Id") %>' /><asp:Button runat="server" ID="Disable" Text="禁用"
OnClientClick="return confirm('你确认禁用该用户?')" CommandName="Disabled" CommandArgument='<%#Eval("Id") %>' />
</td></tr></ItemTemplate>
<FooterTemplate></table></FooterTemplate>

3.增加一个CSS样式

    <style type="text/css">
.disableRow{ background-color:Red;}
</style>

4.ItemDataBound事件

//对于Header等则不处理,必须要判断AlternatingItem,因为默认是加入这个的
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
DataRowView rowView = (DataRowView)e.Item.DataItem; //将当前对象转换成 DataRowView
var userRow = (人员管理.DAL.DataSetT_User.T_UserRow)rowView.Row; //获得当前行成员 if (userRow.Status == "禁用") //如果状态是禁用,则设置它的一些样式
{
HtmlTableRow trRow = (HtmlTableRow)e.Item.FindControl("trRow"); //获得trRow的控件
trRow.Attributes["class"] = "disableRow"; //增加一个calss属性 Button btnenable = (Button)e.Item.FindControl("Enabled"); //获得Enabled控件
Button btndisable = (Button)e.Item.FindControl("Disable"); btnenable.Visible = true; //将btnenable设置为显示
btndisable.Visible = false; //将btndisable设置为不显示
}
else if(userRow.Status == "启用")
{
HtmlTableRow trRow = (HtmlTableRow)e.Item.FindControl("trRow");
trRow.Attributes["class"] = ""; //设置无样式 Button btnenable = (Button)e.Item.FindControl("Enabled");
Button btndisable = (Button)e.Item.FindControl("Disable"); btnenable.Visible = false; //与上面相反
btndisable.Visible = true;
}
else //为了程序的严整性
{
throw new Exception("状态有误!"); //抛出异常
}
}

5.ItemCommand事件

 if (e.CommandName == "Enabled")    //如果CommandName为 Enable
{
int id =int.Parse(e.CommandArgument.ToString()); //获得CommandArgument值
T_UserTableAdapter adpter = new T_UserTableAdapter(); //new 一个adpter
adpter.EnableById(id); //使用自定义SQL方法怎么数据修改
Repeater1.DataBind(); //再次绑定数据
}
else if(e.CommandName == "Disabled") //同上相反
{
int id = int.Parse(e.CommandArgument.ToString());
T_UserTableAdapter adapter = new T_UserTableAdapter();
adapter.DisableById(id);
Repeater1.DataBind();
}
ListView 控件

Repeater一般只用来展示数据,如果要增删改查则用ListView更方便,使用向导(强类型数据)
LayoutTemplate为布局模板,其中必须有一个ID为 itemPlaceholder 的服务端控件,什么类型无所谓
不会被显示,itemPlaceholder前面就是根相当于Repeater中的HeaderTemplate,itemPlaceholder后
面就是相当于Repeater中的FooterTemplate,因此ListView中没有这两个模板itemTemplate是每一项的模板,
AlternatingltemTemplate是隔行显示的模板,和Repeater一样
EmptyDataTemplate为数据源没有数据的时候显示的内容,可实现"没有查找到结果","对不起,找不到你要的数据"等,
InsertItemTemplate为插入数据界面的模板,
EditltemTemplate为编辑数据的模板,
SelectedltemTemplate为标记为Selected的行的模板

在ListView中有些是用 <%#bind() %> 进行数据双向绑定的,更新就是这样实现的

在ListView中使用ItemDataBound为每行数据进行处理
注意:
1.判断数据行的类型e.Item.ItemType ListViewItemType.DataItem
2.取得行对应的DataRowView

 ListViewDataItem lvDataItem = (ListViewDataItem)e.Item;
DataRowView rowView = (DataRowView)lvDataItem.DataItem;

3.在FindControl的时候注意AlternatingItemTemplate的问题,将它的id与ItemTemplate的ID一样

案例:将状态为"禁用"的数据背景改色

先将 ItemTemplate 与 AlternatingItemTemplate 的<tr>的ID设置为一样,否则会有问题

if (e.Item.ItemType == ListViewItemType.DataItem)
{
ListViewDataItem lvDataItem = (ListViewDataItem)e.Item; //必须先转换,调试可得
DataRowView rowView = (DataRowView)lvDataItem.DataItem;
var userRow = (TEST.DAL.DataSetTEST.T_UserRow)rowView.Row;
if (userRow.Status == "禁用") //检测状态是否为 "禁用"
{
HtmlTableRow trRow = (HtmlTableRow)e.Item.FindControl("trRow"); //取得控件ID
trRow.Attributes["class"] = "disabled"; //设置样式
}
}

在ListView中可以使用Validator 验证控件,只要将Validator放入相应的模板中,将Validator手动
设定要验证的控件ID,然后设定相应按钮,控件,Validator为同样的ValidationGroup,防止不两只模板
中的Validator互相干扰,将Cancel按钮(取消)的CausesValidation="false" 达到一取消就返回

新增数据行的默认值:响应ListView的ItemCreated事件(第一行在页面上的创建都会触发该事件)
当e.Item.ItemType为InsertItem的时候通过FindControl找到控件然后初始化

如:给年龄设默认值:ItemCreated事件

    if (e.Item.ItemType == ListViewItemType.InsertItem)//判断是否为InsertItem类型
{
TextBox AgeBox = (TextBox)e.Item.FindControl("AgeTextBox"); //获取年龄控件
AgeBox.Text = ""; //设置插入的默认值
}

插入数据的初始化: 注意和"新增数据行"不同,插入数据的初始化是在用户点击"插入"之后执行,如果
主键为Guid,则需要在数据插入数据库之前为主键赋值,响应ListView的Itemlnserting事件
该事件是将一些插入数据库之前的对数据进行调整的代码
e.Values为所有字段的键值对,可以读取插入的值,也可以向字段中写值,这样就可以为ID赋值
e.Values["id"]=Guid.NewGuid() ,在这个事件中对数据进行校验,可以通过e.Cancel = true 来取消
非法数据插入,注意:ObjectDataSource绑定ID为Guid类型的时候会生成一个"DataObjectTypeName="System.Guid""的东西,有问题的话,删掉就行

如:用程序给ID值设置Guid,如果用户名为xgao,将不给插入

     e.Values["id"]=Guid.NewGuid();            //新建一个 Guid 传给当前id字段
if (e.Values["UserName"].ToString() == "xgao") //判断用户名
{
e.Cancel = true; //取消数据插入
}

更新之前的处理:就像数据插入前可以在ItemInserting事件中处理一样,可以在ItemUpdating事件中
对更新过程进行处理
e.ItemIndex可以取到当前更新行的行号
e.OldValues可以取到更新前的值
e.NewValues可以取到更新后的值
e.Cancel = true来取消非法数据插入

如:更新的用户名长度不能为 9 个以上

 if (Convert.ToInt32(e.NewValues["UserName"].ToString().Length) > ) //当长度大于9时
{
Response.Write("<script>alert('用户长度不能大于9!')</script>");
e.Cancel = true; //取消数据插入
}

ListView 行命令按钮

ListView的行按钮和Repeater一样,不同的是取当前行数据的方式,
int num = ((ListViewDataItem)e.Item).DisplayIndex 取出操作行的行号
ListView1.DataKeys[num].Value 取也主键的值,如果对数据进行了操作,最后对ListView执行DataBind绑定
可以多个主键(和数据库主键没直接关系),所有有Values,是由ListView的 DataKeyNames="id" 值来决定

排序:将LayouTemplate中的表头用
<asp:LinkButton runat="server" CommandName="Sort" Text="id" CommandArgument="id" />控件代替,
其中CommandArgument的值为排序字段只要是CommandName,CommanArgument对就行,展现成什么,显示在哪儿都可以

案例:涨一岁 按钮

1.自定义SQL方法(年龄加1的方法)
update T_person SET age = age+1 where id=@id

2.在ItemTemplate 最后加入

<asp:Button runat="server" ID="INC" CommandName="IncAge" Text="加一岁" />

3.在ListView1的 ItemCommand 事件写如下代码

  int num = ((ListViewDataItem)e.Item).DisplayIndex;    //取得前行号
int id = (int)ListView1.DataKeys[num].Value; //取当前操作行的主键值
if (e.CommandName == "IncAge") //判断当前控件的CommandName是否为IncAge
{
T_personTableAdapter adpater = new T_personTableAdapter();
adpater.IncAgeById(id); //利用自定义SQL语句进行 年龄加1
ListView1.DataBind(); //数据绑定
}
DropDownList控件

ListView中是无法像TextBox等控件那样将DropDownList的选中值绑定到数据的字段,必须编程处理
如果要实现 "----请选择-----" 每次都有的话,得先在Items增加这个值,再设置AppendDataBoundItems为True就行了

如:人员的性别(男,女,保密),三个值固定定在DropDownList中

1. 在显示数据的时候DropDownList显示数据的值,在ItemTemplate中加入DropDownList,设定Enabled="false"
这样就是只读的,在ItemDataBound事件中e.Item.FindControl()来找到DropDownList控件,然后
ListViewDataItem lvData = (ListViewDataItem)e.item;
DataRowView rowView=(DataRowView)lvDataItem.DataItem; //取到DataRowView进而取到DataRow
读取数据的值,然后赋值给DropDownList的SelectedValue属性
2. 在插入数据的时候设定DropDownList对应的字段的值,响应ItemInserting事件,通过e.Item.FindControl
找到DropDownList控件,然后通过e.Values设置值
3. 在数据更新的时候设置DropDornList对应的字段的值,响应ItemUpdating事件,通过ListViewDataItem DataItem

//DropDownList 显示时用 ItemCreated 事件
DropDownList ddlStatus = (DropDownList)e.Item.FindControl("ddlStatus");
if (ddlStatus != null) //如果没有找到ddlStatus ,就认识不是EditTemplete
{
ListViewDataItem lvData = (ListViewDataItem)e.Item;
DataRowView rowView = (DataRowView)lvData.DataItem;
if (rowView != null) //如果取到的话
{
var userRow = (TEST.DAL.DataSetTEST2.T_UserRow)rowView.Row;
ddlStatus.SelectedValue =
}
} //DropDownList 插入时用 ItemInserting 事件
DropDownList ddlStatus = (DropDownList)e.Item.FindControl("defalutStatus");
e.Values["Status"] = ddlStatus.SelectedValue; //e.Values[] 赋值操作 //DropDownList 更新时用 ItemUpdating 事件 DropDownList ddlStatus = (DropDownList)ListView1.Items[e.ItemIndex].FindControl("ddlStatus");
e.NewValues["Status"] = ddlStatus.SelectedValue; //e.NewValues[] 更新数据后赋值操作
DataPager 分页控件

ListView搭配DataPager控件实现分页,有两种使用方式,一种是将DataPager声明到ListView中
别一种是DataPager,ListView没有嵌套关系,然后将DataPager的PagedControllD设定为要分页
的ListView,没什么区别,一般用"配置ListView"自动生成的方式即可,DataPager的PageSize属性
为一页的条数
(*)实现 IPagebleItemContainer接口的控件都可以使用DataPager,但是目前只有ListView实现该接口
DataPager中按钮显示风格由Fields中的字段设置,可以放置多个字段,分为"NextPreviousPagerField"
(下一页,下一页,首页,末页),"NumericPagerField"(数字页号),"TemplatePagerField"用户模板自定义
代码中选择相应的Field,在属性视图中就可以快速修改它们的属性

 高效率分页

ListView默认的分页是先从数据源取得所有数据,然后再截取当前页面的部分,在数据量非常大的情况
下效率非常代,因此默认分页基本不用,应该是只从数据源取得要显示的数据
复习:SQL中语句中取得分页数据 ,SQL语句中获得每一行序号的方法:
select Id, UserName row_number()over(order by id) from T_User
其中row_number()函数是SQL2005之后提供的一个计算结果集行号的函数(不是表的行号),
over()是指定排序规则

案例:取得第11到20的数据(条数从0开始)的方法,使用子查询用行号进行两次处理

select * from (SELECT Id, UserName row_number()over(order by id)rownum
FROM T_User)t
where t.rownum>10 and t.rownum<=20

在强类型DataSet中增加取得所胡数据条数的方法QueryCount,增加取得指定行数范围数据的方法GetPageData

select * from
(select id,name Row_Number()over(order by id)rownum from T_User)t
where t.rownum>@startRowIndex and t.rownum<=@startRowIndex+@maximumRows

由于数据集编辑器不支持(不会自动生成一些东西)Row_Number(),所以创建完成后需要手动在GetPagedData
属性的Parameters中增加两个参数:
startRowIndex 与 maximumRows(参数名必须是这两个,这是由ObjectDataSource的StartRowIndexParamterName,
MaximumRowsParamterName确定的,一般不需要改),都是 Int32类型

ObjectDataSource中EnablePaging属性设置为true,SelectCountMethod设置为QueryCount,SelectMethod
设置为GetPagedData,都是自定义的SQL方法
如果出错的话看看是不是没有放置内置的DataPager或者外置的DataPager的PagedControllD没有指向ListView
先按照正常的流程配置ObjectDataSource,让它自动生成Template,
再修改ObjectDataSource的EnablePaging="True",SelectCountMethod设置为取得行数的方法
DataPager默认是用PostBack机制,显示不到地址中,不利于网友共享,只要指定QureyStringField属性
就可以实现超链接形式的分布链接

单独页面编辑

istView的在位编辑只适合字段较少,比较简单的场合,复杂数据的编辑,插入,查看等要在单独页面中
创建一个单独的页面edit.aspx,然后在ListView页面中的编辑放一个编辑的超链接,向edit.aspx传递
?id=1&action=edit 页面顶端增加一个edit.aspx?action=addnew 的超链接
使用FormView控件进行单条数据的编辑,在Page_Load中判断action,然后使用FormView1.ChangeMode
方法切换FormView的模式
在强类型DataSet中增加一个GetDataByid方法,在ObjectDataSource中选择这个方法为Select参数
参数源为QueryString,QueryStringField为id
在元素插入,修改完成(Inserted,Updated事件)后重定向到列表页面

在edit.aspx中做如下判断:

if (!IsPostBack)
{
string action = Request["action"];
if (action == "edit") //是否为 edit 模式
{
FormView1.ChangeMode(FormViewMode.Edit); //更改模式为 编辑模式
}
else if (action == "new") //是否为 new 模式
{
FormView1.ChangeMode(FormViewMode.Insert); //更改模式为 编辑模式
}
else if (action == "view") //是否为 view 模式
{
FormView1.ChangeMode(FormViewMode.ReadOnly); //更改模式为 编辑模式
}
}