2004-4-27+ Repeater和DataList的精确定位
精确定位这个词是我自己瞎想的,我不知道正规的说法是什么。用这个词主要是用来解决这个问题:比如你用repeater写了一个留言本,可是当你要回复具体的留言的时候,怎么才能获得这个留言的具体位置呢?再说一种情况,以前我们写asp的时候,经常会用到形如“http://api.533.net/needquest.asp?id=notus”的语句,这个主要是用来传递值给需要的页面,并且每一条记录所要传递的值是不同的。如果我们的页面是用datalist构成的,有没有更好的方法来实现在单个页面内传递值呢?还有一个现成的例子,我前几天写的repeater留言本就碰到了这样的情况,有兴趣的可以查看一下第7篇文章。
最近几天,我终于发现了解决的办法,repeater和datalist的itemcommand事件就提供了捕获用户事件的方法。itemcommand事件提供了可以传递信息的repeatercommandeventargs对象和datalistcommandeventargs对象。通过其提供的方法我们可以轻易的获得所需要的信息。
<%@ Page Language="C#" ContentType="text/html" ResponseEncoding="gb2312" %>
<%@ import namespace="System.Data"%>
<%@ import namespace="System.Data.OleDb"%>
<script language="c#" runat="server">
OleDbConnection conn;
private void Page_Load(object sender,System.EventArgs e){
if(!Page.IsPostBack)
bind();
}
private void bind(){
string connstr=ConfigurationSettings.AppSettings["color"];
conn=new OleDbConnection(connstr);
string sql="select * from cb0102";
OleDbCommand cmd=new OleDbCommand(sql,conn);
conn.Open();
rep1.DataSource=cmd.ExecuteReader();
rep1.DataBind();
conn.Close();
}
//处理点击事件的方法,注意RepeaterCommandEventArgs提供了捕获用户事件的方法,其中的一个是由Item提供,如果是DataList,当然就要换成DataListCommandEventArgs,以后的代码是一样的
private void rep1_ItemCommand(object source,RepeaterCommandEventArgs e){
//这是第一种方法,CommandSource接收触发事件的控件的信息,这个信息是确定的单个控件,即你点哪个按钮,它就会返回那个按钮的信息。注意格式的转换。这个方法现在被注释掉了
//lb1.Text=((LinkButton)e.CommandSource).CommandArgument.ToString();
//这是第二种方法,Item.FindControl用来查找触发事件的控件所在行的其他控件的信息(当然包括它本身),要调用这个信息,就需要明确的指出是哪一个控件。注意格式的转换。从某种意义上来说,这种方法更有用一些,因为我们可以在这一行设置一个visible=false的label控件来存放我们需要的信息,这样从页面上看不到这个数据,但是却可以为我们所用,提供了保密性
la1.Text=((Label)e.Item.FindControl("la2")).Text.ToString();
bind();
}
</script>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>repeater的精确定位</title>
</head>
<body>
<%--用来演示效果的label--%>
<asp:Label id="la1" runat="server" Text="ssssdd"></asp:Label>
<form runat="server">
<%--别把OnItemCommand="rep1_ItemCommand"掉了,这个用来确定响应事件--%>
<asp:repeater id="rep1" runat="server" OnItemCommand="rep1_ItemCommand">
<itemtemplate>
<%# DataBinder.Eval(Container,"DataItem.name")%>
<%--这里就是提供传递值的控件,需要注意的是绑定表达式的出现方式'用单引号括起来'--%>
<asp:LinkButton id="lb1" CommandArgument='<%# DataBinder.Eval(Container,"DataItem.classid")%>' runat="server" Text="here"></asp:LinkButton>
<asp:LinkButton id="lb2" CommandArgument='<%# DataBinder.Eval(Container,"DataItem.sex")%>' runat="server" Text="here"></asp:LinkButton><br>
<%--这个从html页面是看不到的,在用第二种方法的时候可以传递值--%>
<asp:Label id="la2" Visible="false" runat="server" Text='<%# DataBinder.Eval(Container,"DataItem.id")%>'></asp:Label>
</itemtemplate>
</asp:repeater>
</form>
</body>
</html>
演示程序就是这样,先是在repeater里安置好控件,并将需要的值绑定到控件,然后引发itemcommand,处理事件的方法根据需要从e获取值,并将这个值赋于某个变量,然后就可以使用这个传回来的值进行下一步操作。如果这个是一个留言本,我们将la2的值设为留言的id,这样当我们点击回复按钮时,就可以容易的用传回来的id确定要回复哪一条留言,然后进行下一步操作。