去除Asp:DataGrid中无用ViewState的方法(1)

** 去除 ** ** DataGrid ** ** 中无用的 ** ** ViewState ** ** 数据 ** ** 的方法 **

** 一、 ** ** DataGrid ** ** 控件中的 ** ** ViewState **

在 Asp.Net 中,我们使用最多的恐怕就是 DataGrid 列表控件了。这个控件的功能的却非常强大,也非常好用。它不但可以实现任意的格式化选择,而且还可以动态进行分页、排序、添加按钮、动态编辑等功能。可以说, DataGrid 控件已经实现了我们需要的大部分功能。

遗憾的是,上面说的很多非常实用的功能,大部分需要 ViewState 的支持,就是说 DataGrid 控件需要通过 ViewState 来保存控件的状态的,如果我们关闭了 ViewState ,即在 HTML 代码中使用了 EnableViewState = "False" 属性,那么,上面的所有有用的功能我们将无法使用。

而 ViewState 的缺点也是很大的,就是 DataGrid 会把所有的数据源中的数据存放到 ViewState 中。 DataGrid 是一个列表控件,它存放在 ViewState 中的数据包括了列表中所有单元格( Cell )中的数据,更加可恨的是,即时我们打开了分页功能,它也要把所有的没有显示出的数据源中的数据放到 ViewState 里面,如果不在数据库端控制数据量大小的话, DataGrid 控件实际上是把数据库表中所有数据统统都存放在 ViewState 中。直接后果就是 Asp.Net 生成发送到客户端的源 Html 代码异常庞大。

大家知道, Asp.Net 中, ViewState 实际上是一个名称 / 值对的字典,为了正确在各种编码的网页中保存,将 ViewState 序列化后又进行了 Base64 编码。这将更加加大 ViewState 的数据量。

我试验了一下,一个包括 5000 条记录的数据库,如果不在数据库端控制数据量的话,直接使用 Select * From TableName 这样的 Sql 语句绑定数据的话,一个 Asp.Net 动态网页(仅有一个 DataGrid 控件的测试页)的 ViewState 有 60k 之多。而这样一个网页放到公共 Web 网站,缓慢的网页下载速度将会使大部分人望而却步,使用 56k 猫上网的人就更不要提了,根本无法访问这样的网页,等待的时间将不可忍受。

所以大部分有 Asp.Net 开发经验的开发者,如果不使用 DataGrid 的高级功能的话,一般是把 EnableViewState = "False" 属性给加入的,还有就是使用自己的分页控件,不使用 DataGrid 提供的分页功能,这将取消 DataGrid 的 ViewState ,大大减少最终生成的 Html 的代码量。

** 二、 ** ** DataGrid ** ** 中必须使用 ** ** ViewState ** ** 的一些功能 **

不错,很多情况下我们仅需要 DataGrid 的显示列表数据的功能,或者使用自己的分页功能,这种情况下可以使用 EnableViewState = "False" 属性,但是如果我们需要使用 DataGrid 的动态编辑、按钮列,或者要访问 DataGrid 的索引项时,我们必须把 DataGrid 的 ViewState 打开,这将不可避免的出现 ViewState 数据量过大的现象,但是我们没有办法。

我大略统计了一下 DataGrid 中需要使用 ViewState 的一些功能属性,它们都必须使用 ViewState ,而这些属性我们很多情况下都必须使用:

DataGrid. CurrentPageIndex DataGrid 分页的页索引

DataGrid. DataKeys 取每个记录的键值

DataGrid. EditItemIndex 编辑项的索引

DataGrid. Items DataGrid 中行的集合

DataGrid. PageCount DataGrid 分页的总页数

而在使用 DataGrid 内置事件时,传递事件参数的 DataGridItemEventArgs 、 DataGridCommandEventArgs 、 DataGridSortCommandEventArgs 、 DataGridPageChangedEventArgs 类更加要使用 DataGrid 的 ViewState ,否则它们将无法工作。

这里我给一个简单的示例,在 DataGrid 中加入一个 CheckBox 列,这使当页面回发的时候我可以获取 DataGrid 的键值。但是如果关闭 ViewState 的话,此功能无法使用。

Html :

< Asp:DataGrid ID = ”myDataGrid” Runat = ”Server” DataKeyField = ”ID” AutoGenerateColumns = ”False” >

< Columns >

< asp:TemplateColumn >

< ItemTemplate >

< Asp:CheckBox ID = ”myBox” Runat = ”Server” /> < br />< br />

< Asp:Button ID= ”bntSubmit” Runat= ”Server” Text= ”OK” />

Code :

private void btnSubmit_Click( object sender, System.EventArgs e)

{

CheckBox cb;

string str;

for (int i=0;i<myDataGrid.tems.Count;i++)

{

cb = (CheckBox)myDataGrid.Items[i].Cells[2].FindControl( "myBox" );

if (cb.Checked)

str += myDataGrid.DataKeys[myDataGrid.Items[i].ItemIndex].ToString();

}

// 此时 str 变量就是 DataGrid 中选中行的数据库键值。

}

上面的代码使用很成功,不过如果在 DataGrid 中使用了 EnableViewState=”False” 属性,那么上面的代码根本无法起作用。

Published At
Categories with Web编程
Tagged with
comments powered by Disqus