Posted on 2006-08-23 18:52
大大毛 阅读(576)
评论(0) 编辑 收藏 所属分类:
ASP.NET
Repeater控件,共有五个模板,编辑该控件的模板只能在ASP源码中进行
1.ItemTemplate,正常显示项,如果定义了交替项模板,则仅代表奇数Item(从1开始算)
2.AlternatingItemTemplate,交替项,代表偶数Item
3.HeaderTemplate,页眉,在控件的最前
4.FooterTemplate,页脚,在控件的最后
5.SeparatorTemplate,分隔项,位于各Item之间,如使用<br/>实现各项换行
适用于:
替代只读显示容器内容的循环,如将一个ResultSet显示成一张表。
HeaderTemplate中使用<table><tr>,ItemTemplate/AlternatingItemTemplate中使用<td></td>,SeparatorTemplate中使用</tr><tr>,FooterTemplate中使用</tr></table>可以实现一个 <table> 元素效果。
DataList控件,共有七个模板
6.SelectedItemTemplate,选择项
7.EditItemTemplate,编辑项
适用于:
可编辑数据的显示,因此在普通的DataSource指定后2006年8月24日,需要绑定数据源的主键列(指定控件的DataKeyField属性)。
该控件提供了多种事件,由放在Item中的Button控件激发。
Button控件将会激发ItemCommand事件,可通过传入的事件参数来引发其它事件,例如使用SelectedItem模板:
protected
void
DataList1_ItemCommand(
object
source, DataListCommandEventArgs e) {
if
(e.CommandName
==
"
Select
"
) {
//
判断激发事件的Button.CommandName
this
.DataList1.SelectedIndex
=
e.Item.ItemIndex;
//
让激发事件的行被选中
myDataBind();
//
这里需要进行重新绑定
}
}
使用EditItemTemplate模板,将Button.CommandName指定成"edit"即可。
protected
void
DataList1_EditCommand(
object
source, DataListCommandEventArgs e) {
this
.DataList1.SelectedIndex
=
-
1
;
//
放弃选择
this
.DataList1.EditItemIndex
=
e.Item.ItemIndex;
//
让当前行进入编辑状态
myDataBind();
}
在EditItemTemplate模板中可以将允许修改的列绑定到子控件上,并放入两个Button,CommandName分别指定为"update","cancel"与DataList的事件相对应,再在对应的数据更新/放弃事件中编程即可。
Cancel事件
protected
void
DataList1_CancelCommand(
object
source, DataListCommandEventArgs e) {
this
.DataList1.EditItemIndex
=
-
1
;
//
放弃编辑状态
myDataBind();
}
Update事件
protected
void
DataList1_UpdateCommand(
object
source, DataListCommandEventArgs e) {
string
id
=
this
.DataList1.DataKeys[e.Item.ItemIndex].ToString();
//
获取编辑行所对应的主键
SqlConnection con
=
Db.getConnection();
//
根据主键更新数据库
SqlCommand cmd
=
new
SqlCommand(
"
update vote set topic=@topic where vID=@vID
"
, con);
SqlParameter p1
=
new
SqlParameter(
"
@topic
"
, SqlDbType.VarChar,
20
);
p1.Value
=
((TextBox)e.Item.FindControl(
"
txtTopic
"
)).Text.Trim();
cmd.Parameters.Add(p1);
SqlParameter p2
=
new
SqlParameter(
"
@vID
"
, SqlDbType.Int);
p2.Value
=
id;
cmd.Parameters.Add(p2);
con.Open();
cmd.ExecuteNonQuery();
con.Close();
this
.DataList1.EditItemIndex
=
-
1
;
//
放弃编辑状态
myDataBind();
}
将Button控件的CommandName指定为"delete",可激发数据删除事件:
Delete事件
protected
void
DataList1_DeleteCommand(
object
source, DataListCommandEventArgs e) {
string
id
=
this
.DataList1.DataKeys[e.Item.ItemIndex].ToString();
//
获取编辑行所对应的主键
SqlConnection con
=
Db.getConnection();
//
根据主键更新数据库
SqlCommand cmd
=
new
SqlCommand(
"
delete vote where vID=@vID
"
, con);
SqlParameter p1
=
new
SqlParameter(
"
@vID
"
, SqlDbType.Int);
p1.Value
=
id;
cmd.Parameters.Add(p1);
con.Open();
cmd.ExecuteNonQuery();
con.Close();
myDataBind();
}
通常需要在Update/Delete按钮上加入确认,如果是静态提示可以直接在Button的属性中加入:
<
asp:Button ID
=
"
btnDelete
"
runat
=
"
server
"
CommandName
=
"
delete
"
Text
=
"
删除
"
OnClientClick
=
"
return confirm(
'delete?'
);
"
/>
在这里可以看到,是利用了Button控件的 OnClientClick 属性调用本地的 JS函数 confirm() 来实现确认的功能。如果想提示动态消息(如提示一个ID),偶没有试出来,不过可以写在代码段里,利用ItemCreated事件,这样:

ItemCreated事件
protected void DataList1_ItemCreated(object sender, DataListItemEventArgs e) {
//此事件表示的是Item的建立,而在不同的模板中是会有不同的呈现形式的,因此需要对当前的状态进行判断
//该delete按钮是在正常浏览状态下的,在select/edit状态下并不存在
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem) {
string s1 = "return confirm('你确认要删除ID=";
s1 = s1 + DataBinder.Eval(e.Item.DataItem, "vID");
s1 = s1 + "的投票吗?');";
((Button)e.Item.FindControl("btnDelete")).Attributes.Add("onClick", s1);
}
} 这样一来就可以在Button激发DataList的事件之前进行简单的确认了,不过需要注意的是:
.用这种方式时,在运行时如果有错误是不会有什么提示消息的,而且流程直接向下进行;
.如果同时使用了两种,那么Button上的OnClientClick属性优先。
该控件的显示方式也与Repeater控件大不相同,它的显示方式分为"表"和"流"两种,默认使用表布局。
使用表布局时控件会自动生成一个<table>元素,样式则由各模板对应的<style>指定,在该控件的运用中不应该再使用如Repeater那种自构造<table>元素的方法,因为该控件中经常需要用到FindControls方法,自行加入元素会影响到该方法。
可以看到模板还具有自己所对应的Style,这个样式与当前Item所使用的模块对应,例如选中第1项,如果没有配置<SelectedItemStyle>才会使用<ItemStyle>所定义的样式。
手工分页:
如上面提到的Repeater、DataList控件都没有提供分页的功能,此时可以对数据源进行分页再配合自定义的导航条来实现分页效果。
手工分页,需要用到 System.Web.UI.WebControls.PagedDataSource 对象。
例如:在页面中加入lblPageNo控件以保存当前页号(text="0"),btnPrevious表示上一页,btnNext表示下一页。

新的代码

/**//// <summary>
/// 数据绑定
/// </summary>

private void myDataBind()
{
SqlConnection con = Db.getConnection();

SqlDataAdapter sda = new SqlDataAdapter();
sda.SelectCommand = new SqlCommand("select * from vote",con);

DataTable table = new DataTable("vote");
sda.Fill(table);
//使用了分页
PagedDataSource pds = new PagedDataSource(); //使用一个PagedDataSource对象
pds.DataSource = table.DefaultView;
pds.PageSize = 3; //每页3条记录
pds.AllowPaging = true; //使用分页效果
int pageNo = int.Parse(this.lblPageNo.Text); //取得保留的当前页码,初始值="0"
pds.CurrentPageIndex = pageNo; //设置当前页
//开关上,下页导航按钮
this.btnPrevious.Enabled = !(pageNo <= 0);
this.btnNext.Enabled = !(pageNo >= pds.PageCount - 1);
//将DataList的数据源指向该PagedDataSource
this.DataList1.DataSource = pds;
this.DataList1.DataBind();
this.DataList1.DataKeyField = "vID"; //指定需要绑定的主键列
DataList1.DataBind();

con.Close();
}

//上一页

protected void tbtnPrevious_Click(object sender, EventArgs e)
{
this.lblPageNo.Text = Convert.ToString(int.Parse(this.lblPageNo.Text) - 1);
myDataBind();
}
//下一页

protected void btnNext_Click(object sender, EventArgs e)
{
this.lblPageNo.Text = Convert.ToString(int.Parse(this.lblPageNo.Text) + 1);
myDataBind();
}

排序:
利用数据视图DataView的Sort属性来实现排序,将其属性指定为一个字段名 + 排序规则。
在GridView中列上可以设置SortExpression排序表达式,并在Sorting事件中指定DataView的Sort为该事件的SortExpression即可。
GridView:
就是一个数据表格,在以前的版本中叫DataGrid。它的功能比DataList更为强大,支持数据表格显示、按列的控制(DataList按名字就只支持一列)、列的排序、分页、空页控制等多种功能,可以将DataList看做是一个轻量级的控件,不过从这两种控件的属性及使用方式来看,风格完全不同,这可能也是两控件命名不一的原因吧。