首页 > 开发 > 综合 > 正文

转贴:DataGrid/DataList

2024-07-21 02:21:59
字体:
来源:转载
供稿:网友
,欢迎访问网页设计爱好者web开发。datagrid/datalist在asp.net中的重要性,想必就不用我再强调了,凡显示table类型的数据,大多会使用这两个控件(当然,如果谁还像asp那样写asp.net,那我也没有办法),所以,每个人可能都有自己的领悟,这篇文章,算是抛砖引玉,为大家做个铺垫。

一、方法
1、databind
很简单、最常用的方法。绑定数据用。需要注意的只有一点:执行了这个方法后,datagrid(由于datagrid和datalist极为相似,所以下面的介绍虽然是针对datagrid,但与datalist也相差不远)里面所有的显示绑定数据的控件,都会显示datasource里的数据,其余控件也将初始化成.aspx里设计的状态。


二、属性
1、datasource
有databind的地方,就应该有datasource。如果没有指定datasource而执行databind,那datagrid将什么也不会显示。
datasource一般是dataset、datatable或者dataview。当然也可以绑定datareader或者其他实现ienumerable的类。

2、datakeyfield,datakeys
当你在datagrid中定位一行之后,肯定想知道这行在数据表里的位置,至少有五种方法可以做到这一点,设置datagrid的datakeyfield就是这几种方法之一。
datakeyfield一般设置为数据表的unique字段(否则就没意义了),通过datakey可以得到这一行对应的关键字段的值。
datakeys是datakey的集合,通过行的索引来读取相应行的datakey。

3、edititemindex,selectedindex,currentpageindex,selecteditem
这些属性都很好理解,看名字就知道是什么意思,需要注意的是,设置了edititemindex或者currentpageindex后需要重新执行databind方法(当然,前面提到过,还需要设置datasource)。

4、columns
没什么好解释的,columns就是columns,列的集合,可以设置列的属性,包括visible、headertext、footertext、sortexpression等。
严重注意:自动生成的列,是不包含在columns中的。只有在.aspx中显示声明的列和在代码中添加的列才会被包含在其中。

5、items
俗话说,最后的都是最重要的,把items作为最后一个属性来介绍,正式基于这样的理由。
items是datagriditem的集合,可以遍历当前datagrid中显示数据的datagriditem。
5.1、datagriditem
每一个datagriditem就是datagrid中显示的一行,其中包括:
header            datagrid 控件的标题部分
item            datagrid 控件中的项
alternatingitem        datagrid 控件中的交替项
selecteditem          datagrid 控件中的选定项(由selectedindex设置,通过selecteditem属性或者items[selectedindex]来读取)
edititem          datagrid 控件中处于编辑状态的项(由edititemindex设置,通过items[edititemindex]来读取)
separator          datagrid 控件中项之间的分隔符
footer          datagrid 控件的脚注部分
pager              datagrid 控件的页选择节
注意,datagrid的items属性中不会包含header、footer、pager这三类datagriditem的。
5.1.1、datagriditem的属性
itemindex —— 得到行在items中的索引
itemtype —— 返回行的类型,也就是上面列出的header、item、...、pager
cells —— 返回行包含的所有tablecell(不管是显示声明的,还是自动生成的,不管是可以看见的,还是隐藏掉的),通过tablecell,可以读取cell中显示的文本、包含的控件
严重注意:只有boundcolumn列和自动生成列,才可以通过tablecell.text属性读取显示的文本。hyperlinkcolumn、buttoncolumn、editcommandcolumn都需要将目标控件转换成相应的控件。
比如:
假设datagrid的第一列声明如下
<asp:hyperlinkcolumn datatextfield="au_id" headertext="au_id" datanavigateurlfield="au_id" datanavigateurlformatstring="edit.aspx?id={0}"></asp:hyperlinkcolumn>
读取的时候可以用:
//items[0]表示第一行,cells[0]表示第一列,controls[0]表示cell中的第一个控件(也只有这个控件可以用)
hyperlink link = (hyperlink)datagrid1.items[0].cells[0].controls[0]);
response.write(link.text);
至于模板列(templatecolumn),当然也可以通过datagrid1.items[i].cells[j].controls[n]来获取,然后转换成原来的控件类型再操作,但是还有个更好的办法,就是用findcontrol来查找控件。
findcontrol是system.web.ui.control的方法,可以根据子控件id来查找子控件
比如:
假设datagrid的某一列声明如下
<asp:templatecolumn>
   <itemtemplate>
      <asp:textbox runat="server" id="txtid" text='<%# databinder.eval(container.dataitem,"au_id") %>'>
      </asp:textbox>
   </itemtemplate>
</asp:templatecolumn>
读取方法:
textbox txt = (textbox)datagrid1.items[1].findcontrol("txtid");
response.write(txt.text);
注意:datalist中是没有cell的


三、事件
1、itemcommand、cancelcommand、deletecommand、editcommand、updatecommand
也就是datagrid中,点击button、linkbutton后执行的事件,执行的事件取决于按钮的commandname。其实最主要的一个是itemcommand,而后面四个都只是itemcommand的一小部分,
比如一个按钮的commandname为"cancel",当返回后,首先执行的是itemcommand事件,然后才是cancelcommand事件。

2、pageindexchanged
如果你的datagrid是分页的,那当你在datagrid上点击pager上的1、2、3或者<、>时,就会激发这个事件。
在这个事件里面,你可以用e.newpageindex来读取要改变的页,然后赋值给datagrid的currentpageindex属性,最后不要忘了,还要设置datasource,还要执行databind。
注意:datalist中没有这个事件,如果需要在datalist中分页,可以一段一段的读取数据,然后把当前段的数据绑定到datalist上。

3、itemdatabound,itemcreated
首先要说的是这两个事件的发生时间。
itemdatabound嘛,只要执行了databind方法,就会马上激发这个事件。
itemcreated呢,如果页面是第一次访问(page.ispostback = false),那在第一次执行databind的时候,会先激发itemcreated事件,也就是说,执行了databind后,首先会用itemcreated来建立header行,然后用itemdatabound来绑定header行,再用itemcreated来建立第一行,再调用itemdatabound来绑定第一行,也就是说itemcreated和itemdatabound是交替执行的。
页面返回时,也会执行itemcreated事件,在page_load之前,但是这时候就不会再执行itemdatabound事件了。
所以,如果你想在datagrid里动态添加什么控件,就需要在itemcreated事件中,而不是在itemdatabound事件中。


四、代码片断
1、datagrid显示双层表头
假设你的datagrid有三列,现在想将前两列作为"大类1",第三列作为"大类2",现在,你可以在itemdatabound事件中加入下面的代码:
if (e.item.itemtype == listitemtype.header)
{
    e.item.cells[0].columnspan = 2;
    e.item.cells[0].text = "大类1</td><td>大类2</td></tr><tr><td>" + e.item.cells[0].text;
}
用这个方法可以为任意添加新行。

2、设置绑定列或者自动生成列的编辑框宽度
请在你的itemdatabound事件中加入一下代码:
if (e.item.itemtype == listitemtype.edititem)
{
    for (int i = 0; i < e.item.cells.count; i++)
    {
        textbox txt = (textbox)e.item.cells[i].controls[0];
        txt.width = unit.pixel(50);
    }
}

3、处理在datagrid中的dropdownlist的事件
dropdownlist没有commandname属性,所以不能用itemcommand事件,不过你可以这样试试:
在datagrid的模板列中加入的dropdownlist控件
<asp:dropdownlist runat="server" id="ddl" autopostback="true" onselectedindexchanged="ddl_selectedindexchanged" />
然后你在.aspx.cs中加入一个函数
protected void ddl_selectedindexchanged(object sender, system.eventargs e) //一定要声明成protected或者public,不能是private的。
{
  //在这里就可以加入其他代码
}

3.1、在上面的事件中怎样得到本行其他cell的值呢?
我们知道,datagrid完全是一个table结构的控件,datagrid包含datagriditem,每个datagriditem又包含tablecell,那么,我们就可以在tablecell的某个控件中,利用控件的parent来得到tablecell,再利用tablecell的parent,就可以得到datagriditem了。
protected void ddl_selectedindexchanged(object sender, system.eventargs e) //一定要声明成protected或者public,不能是private的。
{
  dropdownlist ddl = (dropdownlist)sender;
  tablecell cell = (tablecell)ddl.parent;
  datagriditem item = (datagriditem)cell.parent;
  response.write(item.cells[0].text);
}

4、怎样得到header、footer、pager里的控件
方法一:在itemcreated或者itemdatabound中,具体代码就不在多写了
方法二:遍历datagrid的所有item(注意,不是遍历datagrid1.items下的item)
foreach (datagriditem item in datagrid1.controls[0].controls)
{
  if (item.itemtype == listitemtype.header)
  {
    //用item.findcontrol查找相应的控件
  }
}
大家可能会注意到,这里有个datagrid1.controls[0].controls,这表示,datagrid1下,有一个子控件,这个子控件是datagridtable类型,他下面才是datagriditem集合
在datalist中,下面的子控件直接就是datalistitem了,而没有table:
foreach (datalistitem item in datalist1.controls)
{
  //....
}


好了,暂时就写到这里,不完善的地方请大家补充,有错误的地方请大家指正。

谨以此文,献给所有热爱技术、支持论坛发展的朋友
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表