首 页 | 新 闻 | 技术中心 | 第二书店 | 《程序员》 | 《开发高手》 | 社 区 | 黄 页 | 人 才
移 动专 题SUNIBM微 软微 创精 华Donews人 邮
我的技术中心 
我的分类 我的文档
全部文章 发表文章
专栏管理 使用说明



 RSS 订阅 
最新文档列表
Windows/.NET
.NET  (rss)    
Visual C++  (rss)    
Delphi  (rss)    
Visual Basic  (rss)    
ASP  (rss)    
JavaScript  (rss)    
Java/Linux
Java  (rss)    
Perl  (rss)    
综合
其他开发语言  (rss)    
文件格式  (rss)    
企业开发
游戏开发  (rss)    
网站制作技术  (rss)    
数据库
数据库开发  (rss)    
软件工程
其他  (rss)    

积极原创作者 
softj (78)
iiprogram (69)
qdzx2008 (50)
goodboy1881 (14)
wangchinaking (58)
fancyhf (1)
harrymeng (41)
yjz0065 (113)
coofucoo (105)
Drate (69)
CSDN - 文档中心 - .NET 阅读:5225   评论: 6    参与评论
标题   去除Asp:DataGrid中无用ViewState的方法(2)     选择自 TomMax 的 Blog
关键字   .Net,Asp.Net,DataGrid,ViewState
出处  

三、去掉ViewStateDataGrid无用数据

   终于说到正题了,我这篇文章说的就是怎样去掉ViewState中的无用数据,而保留有用的数据。文章写到这里,我们可以很明显的看出来,DataGrid保存在ViewState中的数据分为两个部分,一部分是保存索引用的,就是DataKeysDataItems这样的属性使用的数据,我们把它称之为索引数据。还有一部分是DataGrid中数据源的内容,我们称之为列表数据。

  我们如果把实际上无用的列表数据从ViewState中去除,这样可以大大减小页面ViewState的数据大小,使用DataGridViewState数据量太大的根本原因就是列表数据存放在ViewState中。

  我在微软的.Net Framework SDK文档中没有找到关闭列表数据ViewState的任何内容,就是说微软没有给出DataGrid运行时的任何调用顺序和内部的工作机制。没办法,我使用了一个工具来获得DataGrid的内部工作流程,发现它在数据绑定初始化的时候,生成了一个叫DataGridTable的控件对象,这个对象是继承System.Web.UI.WebControls.Table控件的。而且这个对象是最先加入(使用Controls.Add()方法)DataGrid中的。而且ViewState中的DataGrid列表数据也是这个控件加入到DataGrid中的。实际上,ViewState中的DataGrid的单元格中的数据实际上是System.Web.UI.WebControls.Table控件的SaveViewState()方法给加进去的。这些数据很多情况下是不需要的。

   好,原因找到了,解决问题就好办了,因为微软已经给出了控制DataGrid中子控件的方法。我们既然知道DataGridTable控件是DataGrid中最先生成的控件,那么我们通过DataGrid.Controls属性就可以直接获取DataGrid中子控件的引用,获得引用后就可以控制子控件了。解决方法就是在数据绑定的时候,设置DataGridDataGridTable控件的EnableViewState属性为False就可以了。

代码如下:

首先必须重写DataGrid.ItemDataBoundDataGrid.ItemCreated事件,我们用它们来控制在向客户端写html之前DataGrid的动作。这两个事件任选其一,都可以实现效果。我们使用ItemDataBound事件来写例子,DataGrid示例IDmyDataGrid

[C#]

首先在页面初始化中的InitializeComponent()方法内加入事件的委托:

private void InitializeComponent()

{

    this.myDataGrid.ItemDataBound +=

new DataGridItemEventHandler(this.myDataGrid_ItemDataBound);

}

然后在myDataGrid_ItemDataBound方法内加入控制代码:

private void myDataGrid_ItemDataBound(object sender, DataGridItemEventArgs e)

{

    myDataGrid.Controls[0].EnableViewState = false;

}

 

[VB.Net]

Private Sub myDataGrid_ItemDataBound(sender As Object,e As DataGridItemEventArgs) _

Handles myDataGrid.ItemDataBound

 

    myDataGrid.Contols.Item(0).EnableViewState = False

 

End Sub

 

好了,使用DataGrid时,把上面的代码加入,将减小使用DataGridViewState90%的数据量。而且,DataGrid中许多使用ViewState的功能丝毫不少,岂不是两全其美?

 

注意:

1.上面说的法子有一种情况下不能使用,就是使用DataGrid的内部分页功能时,重写DataGrid.PageIndexChanged事件时,调用DataGridPageChangedEventArgs时,必须把所有的ViewState打开,包括列表数据,关闭任何的ViewState,都将导致DataGridPageChangedEventArgs的索引丢失,无法分页。

不过这个缺点很好解决,很多人已经写了自定义的分页控件,这些控件是不需要DataGrid的任何数据的。可以提供非常完美的分页功能。

2. (重要)我春节的这几天对上面说的办法进行了详细的测试,发现上面的办法确实有效,可以大大的减少aspx页面的ViewState的数据量,但是这个办法在使用上有一个注意的地方,否则会出现数据无法显示的毛病。

我一直在奇怪,微软写DataGrid为什么要加入一个DataGridTable类,而且还要把所有的数据库数据存放在ViewState中。经过测试我才发现,这是因为有了System.Web.UI.Page.IsPostBack属性的缘故。我们经常喜欢利用Page.IsPostBack属性检测页面是否是第一次运行,如下代码:

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

{

    if(!Page.IsPostBack)

    {

       // 页面第一次运行,执行数据绑定

       SqlConnection conn = new SqlConnection(“...”);

       SqlCommand comm = new SqlCommand(“...”,conn);

       ...

       ...

       myDataGrid.DataBind() // 数据绑定

    }

}

当然,网页执行第一次时,DataGrid的内容正常显示,而使用了上面的去除ViewState方法后,页面如果回发处理,DataGrid的内容将会消失。我才明白DataGridDataGridTable把数据存放在ViewState内的用意。微软的设计是非常严谨的,他们的用意就是当使用Page.IsPostBack属性时,仅访问一次数据库就可以永久保持DataGrid的数据(在不离开此页面的情况下),数据存放的地点就是页面的ViewState中。这样页面回发后,DataGrid就可以从ViewState中重新生成DataGrid的显示内容,无需访问数据库。所以说微软以牺牲客户下载的速度(ViewState数据量)来保证服务器的资源,大家都知道频繁访问数据库对服务器的资源消耗很大。

所以,使用上面减少DataGridViewState数据的法子是可行的,但是必须使所有的页面回发处理都必须进行数据绑定,否则DataGrid无法获得数据库内容,也无法获得ViewState中保存的数据,那么回发后DataGrid将无法显示任何内容。

总结,使用上面减少ViewState的办法可以大大加快客户端的下载显示速度,但是频繁的数据库访问将加大服务器的压力;使用ViewState可以减轻服务器的压力,但是又加大了客户端的下载时间,它们是互相矛盾的。所以开发者要根据实际情况选择是否使用DataGrid.Controls[0].EnableViewState=false;的法子,如何选择,大家请自己斟酌。


相关文章
对该文的评论
googie ( 2004-11-23)
Controls 不是 System.web.ui.webcontrol.datagrid.的成员
googie ( 2004-11-23)
不管用哎!
menuvb ( 2004-05-31)
解决了我前段时间碰上的问题
jonescheng ( 2004-02-21)
用DataGrid控件确实比较方便,我也想知道
进行了缓存对提高呈现速度有帮助呢?
buptsnowpeak ( 2004-02-01)
在使用微软的DataGrid控件时,确实有些困惑,编写自定义的分页空间有比较麻烦,不知道把数据进行缓存是否有助于改善性能呢?