[ASP.NET学习笔记之十七]ASP.NET DataGrid 高级使用技巧

来源:互联网 发布:nginx bad request 编辑:程序博客网 时间:2024/06/05 20:39

ASP.NET DataGrid 高级使用技巧

传统ASPASP.NET在数据呈现方面的比较

 

ASP

建立数据库连接
SQL查询装载ADO数据集

显示所需要的任何HTML

代码
   遍历数据集中的记录

   输出记录字段值及相关的
HTML
   移向下一条记录

 循环

显示所需要的HTML代码

缺点

*       不符合MVC架构

*       可重用性差

*       分页采用SQL top方式,同时还须计算页码

*       可读性差

ASP.NET

转载数据到Dataset
datagrid.DataSource = dataset
datagrid.DataBind()

 

*       符合MVC

*       绑定数据方便

*       支持各种数据操作,可方便地实现分页、编辑、排序等操作

 


三种数据绑定控件的使用领及选择

DataGrid优缺点

优点:

*       灵活性强,内置事件丰富

*       提供分页、编辑、排序等特性

*       功能强大的DataGrid编辑器以及模版列

*       快速开发、容易部署

*       对于表格的操作非常方便

*       内置多种布局风格

缺点:

*       性能不高(因为每次操作必须postback回服务器)

*       个性化输出数据有限(只能输出html表格)

DataList优缺点

*       拥有强大的模版特性,灵活性高

*       支持数据的编辑状态

*       性能优于DataGrid

*       开发周期略比Datagrid

*       没有Datagrid编辑器

*       不容易实现分页和排序功能

Repeater优缺点

*       控件完全以HTML方式呈现,更加个性化

*       不支持编辑、分页、排序功能

*       开发周期最长

*       不提供默认的风格,须手工编写

*       性能最好,但特性最少

三者使用范围

*       Datagrid: 主要用在含有数据的表格中,一般数据源是一个dataset。对于有排序、分页、多列显示、对性能要求不是很高一般选用Datagrid

*       DataList: 主要用于单列的数据列表、高性能的自定义的数据表、每行多条记录,如:电子相册(含分页)

*       Repeater:主要应用一些灵活性、性能更高的一些数据展现

性能比较(压力测试)

注意事项:

*       Datagrid生成过大的ViewStateBase64),导致性能最差

*       处在WebForm节点下的控件性能要优于无WebForm下的控件

DataGrid 整体介绍

要点:

*       Datagrid类似于数据库的表格

*       记录集由行集(items)和列集(columns)组成

*       行集由多个datagridColumn组成

*       列集由多个datagriditem组成

DataGrid Column的介绍

*       BoundColumn:文本字段标准显示,当处于编辑状态,将显示为TextBox

*       HyperLinkColumn:显示文本数据,同时是一个URL超链接

*       ButtonColumn:按钮列,包括:

 

选择按钮

无后台事件,可改变选中行的颜色

删除按钮

DeleteCommand事件

更新按钮

UpdateCommand事件

编辑按钮

EditCommand事件

普通按钮

ItemCommand事件

 

风格:LinkButtonPushButton;

 

TemplateColumn:模版列,完全控制哪些控件显示给用户;分为多种模版,如图

HeaderTemplate

用于对页眉的自定义操作

ItemTemplate

项模版,用于显示自定义数据

EditItemTemplate

编辑模版,即:当控件处于编辑状态时,该单元处于哪种状态。

FooterTemplate

用于对页脚的自定义操作

注意事项:非模版列均可以转换为模版列来增加更灵活的功能

使用DataGrid注意事项

*       需要更大的灵活性时,建议不要使用自动生成的列。

*       如果设置了自动生成列,并且在 Datagrid 中指定了列,那么最终将得到对列的重复设置。系统将首先显示特别声明的列,随后是所有自动生成的列。

*       切忌不可仅使用控件 ID 来引用 Datagrid 项目中的控件

       例如: 定义了一个textbox1textbox控件,事实上,为了确保idhtml里不重复,每行的textbox前都加上了不同的前缀,

如:DataGrid1:_ctl2:MyTextBox _ctl2: 代表textbox1的当前行。

       须用FindControl 来指明

 

DataGrid Item 介绍

注意事项:

对于非模版列:datagriditem.Cells[第几个单元格].Controls[第几个控件]

下标从0开始

可以转换成相应的控件,如:

boundColumn: Label     EditColumn: TextBox  LinkColumn:DataGridLinkButton …

模版列Controlindex必须都加一,因为Control[0]LiteralControl=“ ”

 

建议:

当知道控件ID值,建议采用datagriditem.findcontrol[“控件名称”] 来获得

DataGrid Item 构建行的流程(itemcreated)

 

DataGrid绑定事件的触发流程

注意事项

*       DataBinding:只要执行了DataBind方法,就会马上激发这个事件。

*       ItemCreated主要是创建行(行容器),ItemDataBound将数据存放于该行容器中(数据绑定)。依次循环

*       如要在创建时手工添加自定义控件(不使用模版列),则需要在ItemCreated事件中绑定

 

DataGrid绑定事件的常见问题

*       引用e.Item.DataItem 报错对象不能为null ” 

原因:没有在itemcreateditemdatabound下判断行类型.

   (DataRowView)(e.Item .DataItem)  只有在: item行、AlternatingItem行、selecteditem行、edititem行才有值

*       数据绑定完之后如何访问某行数据?

可以使用datagriditem来搜索,代码结构如下:

   for each (datagriditem dgi in Datagrid1.items)

   {   

}

切记:不可用dgi.dataitem 来访问,因为在itembound之后已重新为null

使用ItemCreated事件注意事项

private void DataGrid1_ItemCreated(object sender,DataGridItemEventArgs e)

{

    if (e.Item.ItemType == ListItemType.Item)

    {

        //此处添加对类型为Item的代码,

    }

}

当加载、修改行属性或者行内的控件属性时,应该判断ItemType类型,因为每个单元格均有不同的项类型的呈现方式,如下表

数据绑定浅谈

简单属性

<%# custID %>

集合

<asp:ListBox id="List1" datasource='<%# myArray %>' runat="server">

表达式

<%# ( customer.First Name + " " + customer.LastName ) %>

方法结果

<%# GetBalance(custID) %>

*       注意:

   ASP.NET 数据绑定语法仅在调用 DataBind 方法时计算 

 

模版列的数据绑定1

*       Container.DataItem容器方法:

  DataItem指的是Datagrid某一行(可通过类型转换成DataRowView,并可以获取该行中的每个单元),即DatagridItemContainer.DataItem 功能相同。

   例如:

    1)循环获取已绑定的datagrid中列名为CustomerID(后期)

string str="" ;

foreach(DataGridItem dgi in DataGrid1.Items)

{                   

str +=((DataRowView)dgi.DataItem).Row["CustomerID"];

}

模版列的数据绑定2

2)在绑定datagrid数据的过程中获取CustomerIDItemDataBound事件)

private void DataGrid1_ItemDataBound (object sender,      System.Web.UI.WebControls.DataGridItemEventArgs e)

{      string str="";

     if(e.Item.ItemType==ListItemType.Item)

     {

        str +=((DataRowView)e.Item.DataItem).Row["CustomerID"];

     }

}

注意:DataItem仅适用于 DataGrid 控件中的数据项。即ListItemType必须是ItemAlternatingItemSelectedItem EditItem 才能访问,所以要加判断。

模版列的数据绑定3

*       DataBinder.Eval
<%# DataBinder.Eval(
数据项的命名容器 ,数据字段名 ,格式字符串 %>

对于DatagridDataListRepeater的命名容器:Container.DataItem 

 

 缺点:性能不高(由于Eval采用反射机制)

DEMO: 实现有序的编号,体现数据绑定的强大

 

ItemCommand事件

*       模版列中的子控件的事件--冒泡事件

 参见MSDN

       EditCommandDeleteCommand UpdateCommand,它们是冒泡事件的特殊事例。

 

好处:它的参数使您可以发现是哪个控件引发了该事件,从而避免了为子控件编写事件模型

提问:如果子控件没有commandName属性怎么办(dropdownlist)?

 

个性化分页技巧

 

分页栏

Label

LiteralControl

DataGridLinkButton

Label:负责显示当前页,也就是选择页.
LiteralControl
:负责显示一个空格,用来间隔它们之间的距离
DataGridLinkButton
:显示连接,用来连接到其它页,如下一页.

 

 

DataGridLinkButton

LiteralControl

默认的只有数字,可以在ItemCreated事件中的ItemType==ListItemType.Pager修改默认的呈现

 

【实例代码】

制作个性化的分页

 

对于DataList分页,必须利用sqlDataAdapter填充方法来实现分页

Datagrid的点击列头之后的升降序技巧

主要步骤:

*       设置允许排序

*       设置每个列的排序表达式 

*       调用事件SortCommand,当点击header的连接将触发该事件

【实例代码】

private void DataGrid1_SortCommand(object source, DataGridSortCommandEventArgs e)

              {

                     ViewState[Sort]=e.SortExpression;获取表达式

                     if ((string)ViewState["orderby"]=="asc")

                            ViewState["orderby"]="desc";

                     else

                            ViewState["orderby"]="asc";

                     bindDate();

              }

 

if (e.Item.ItemType==ListItemType.Header)

       {

              foreach(TableCell c in e.Item.Cells)

       {

                                  

              if (c.Controls.Count >0 && c.Controls[0].GetType().ToString()=="System.Web.UI.WebControls.DataGridLinkButton")

              {

               if (((LinkButton)c.Controls[0]).Text==(string)ViewState["Sort"])

                 {

                      Label l=new Label();

                      l.Font.Name="Webdings";

                      if ((string)ViewState["orderby"]=="asc")

                     l.Text="5";

                      else

                       l.Text="6";

                      c.Controls.Add(l);  //添加标记到header

                                          }

                                   }

                            }

                     }

 

void bindDate()

              {

                     sqlDataAdapter1.Fill(dsCustomers1,"Customers");

                     DataView dv=new DataView(dsCustomers1.Customers);

                     if ((string)(ViewState["Sort"])!="")

                     {

                            dv.Sort=(string)ViewState[“Sort”]+“ ”+ViewState[“orderby”];    //设置dataview的排序

                           

                     }

                    

                    

                     DataGrid1.DataSource=dv;

                     DataGrid1.DataBind();

              }

 

DataGrid插入空行

*       思路:

    采用在页脚处插入空行的做法

*       主要步骤:

  1) itemcreated事件中插入新行及按钮

  2) 设置按钮的comandname

  3) itemCommand事件中编写插入代码

DataGrid自定义列的封装

*       为什么要实现封装?-- 提高灵活性、可复用性

*       继承DatagridColumn

DatagridColumn属性:

FootStyle

FootText

HeaderImageURL

HeadStyle

HeadText

ItemStyle

SortExpression

Overrides

DataGrid自定义列的方法

*       Initialize

*       InitializeCell  (=Datagrid中的itemcreated)

*       LoadViewState

*       OnColumnChanged

*       SaveViewState

*       TrackViewState

【实例代码】

构建自定义列

 

DataGrid封装成自定义组件

*       最主要的重载函数InitializeItem

protected virtual void InitializeItem( DataGridItem item, DataGridColumn[] columns );

Columns:该行的所有列

TableCell      

列的InitializeCell

Datagriditem.cells集合中

 

【实例代码】

构建自定义的Datagrid

 

小结

*       Itemcreated绑定行控件,itemdatabound绑定行数据

*       必需要判断ListItemType的类型

*       可以通过Itemdatabound或者后期循环获取的方式来获取数据或控件

*       采用datagriditem.findcontrol[“控件名称”]来获取控件

*       通过itemcreated可以修改控件、加载控件等

*       datagrid代码过多或使用次数过多时,尽量编写自定义的datagrid或者自定义列

*       自定义列中一般重载InitializeCell(itemcreated)

*       自定义datagrid中一般重载InitializeItem

 

 
原创粉丝点击