Net - GridView TemplateField Column信息丢失问题
2006-09-11
环境VS2005
状况:
如下图所示,查看、修改、删除三个列是在aspx页面中使用TemplateField指定的,后面的象用户代码、用户姓名等列,是程序在代码中创建的Column,然后Add到GridView的Columns中。
aspx页面中的TemplateField代码如下:
动态添加的Column代码类似如下:
BoundField col = new BoundField();
col.DataField = "UserCode";
col.HeaderText = "用户工号";
this.gv.Columns.Add(col);
现在需要实现一个功能,即用户能够对GridView里面显示哪些栏位、显示顺序进行调整。做法是,将列的信息抛转到一个设置页面,设置栏位的显示、栏位顺序等,设置完后,再将列的信息返回。页面根据新的设置,重新调整GridView里面的Column。
因为没有方法可以将GridView的Column MoveTo(index)方式进行调整,所以先将查看、修改、删除之外的Column Remove掉,然后再根据新的设置重新Add Column。
for( int i = this.gv.Columns.Count-1; i > 2; i--)
{
this.gv.Columns.RemoveAt(i);
}
接下来按照新的设置,重新为GridView添加列。
这样处理完之后,紧接下来,任何服务器端事件发生时,查看、修改、删除的列信息就会被丢掉,变成空白。
只要是对GridView的Columns调用Remove、RemoveAt、Clear等方法,上面的情况就会出现。应当是GridView的一个Bug,估计应当是调用这些方法之后,没有正确的更新ViewState值,导致Columns集合中的对象与ViewState值出现不匹配,这样在页面重新PostBack时,生成的Columns对象中导致TemplateField信息丢失。
解决方法:
1. 正式的解决方法,比较麻烦。不在aspx页面指定TemplateField的列,而是在后台用代码生成这些列。或者从TemplateField继承,写自己定制的TemplateField对象,同样在代码中进行加载。
为什么说比较麻烦,因为需要在Column中添加控件,设置属性,还要绑定服务器端事件等。
2. 投机取巧的办法。不调用Columns的Remove或者RemoveAt方法,而是将相关Column的Visible属性设置为false,将Column隐藏起来,接下来在Columns中添加新的列。
这样做,从功能界面上看,没有什么问题,达到了实际效果。但实际上,GridView的Columns里面将会包含那些被隐藏了的列。在上面举的例子中,将会造成GridView中出现重复的列。因为我不使用GridView进行编辑操作,仅仅是显示而已,所以不会有问题。
另外,对于那些Visible被设置为false的列,并不会为这些列生成HTML代码,而只是把被隐藏的列的信息保存在了ViewState中。如果你每次PostBack时都隐藏部分列,添加新的列,这样你会看到随着页面的刷新,ViewState值越来越长。
yudi500
发表于 >2006-09-11 14:10:54 [评论 0] [浏览
0]