zoukankan      html  css  js  c++  java
  • ASP.NET中DataGrid和DataList控件用法比较

    ASP.NET中DataGrid和DataList控件用法比较
    很久以前就想写一些关于DataGrid/DataList的东西,但是一直以来,一方面自感所学未深,另一方面,总觉无从下笔,一拖再拖,离刚开始的念头已距一年有余。
    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)
    {
      //....
    }

  • 相关阅读:
    OnEraseBkgnd、OnPaint与画面重绘
    .编译ADO类DLL时报错的解决方案
    VC列表框样式
    Codeforces 131D. Subway 寻找环树的最短路径
    Codeforces 103B. Cthulhu 寻找奈亚子
    Codeforces 246D. Colorful Graph
    Codeforces 278C. Learning Languages 图的遍历
    Codeforces 217A. Ice Skating 搜索
    Codeforces 107A. Dorm Water Supply 搜图
    Codeforces 263 D. Cycle in Graph 环
  • 原文地址:https://www.cnblogs.com/juan/p/1425112.html
Copyright © 2011-2022 走看看