首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网站开发 > asp.net >

请教关于datakeynames设置多个字段的有关问题

2012-01-26 
请问关于datakeynames设置多个字段的问题因为gridview中有好几个隐藏列需要读取数据,所以采用了datakeynam

请问关于datakeynames设置多个字段的问题
因为gridview中有好几个隐藏列需要读取数据,所以采用了datakeynames,查阅msdn得到:

如果将某个列字段的   Visible   属性设置为   false,则在   GridView   控件中将不显示该列,该列中的数据也不会往返于客户端。如果希望某个不可见的列中的数据可以进行往返,则向   DataKeyNames   属性添加相应的字段名称。
若要以声明方式设置此属性,请使用以逗号分隔的字段名列表。

故采用了如下代码:
asp文件中(ABCDE为各列datafield):
        <asp:GridView   ID= "GridView1 "   runat= "server "   CellPadding= "4 "   ForeColor= "#333333 "   GridLines= "None "   onrowdatabound= "CustomersGridView_RowDataBound "   AutoGenerateColumns= "False "   DataKeyNames   = "A,B,C,D,E "   >
                <Columns>
                        ………………
                        <asp:BoundField   DataField= "A "   Visible   =false   />
                        <asp:BoundField   DataField= "B "   Visible   =false   />
                        <asp:BoundField   DataField= "C "   Visible   =false   />
                        <asp:BoundField   DataField= "D "   Visible   =false   />
                        <asp:BoundField   DataField= "E "   Visible   =false   />
</Columns> </asp:GridView>

cs文件中:
protected   void   CustomersGridView_RowDataBound(Object   sender,   GridViewRowEventArgs   e)
        {
                        if   (GridView1.DataKeys[0].Value.ToString()   ==   "1 ")
                                row.Cells[2].Text   =   "a ";
                        else   if   (GridView1.DataKeys[1].Value.ToString()   ==   "1 ")
                                row.Cells[2].Text   =   "b ";
                        else   if   (GridView1.DataKeys[2].Value.ToString()   ==   "1 ")
                                row.Cells[2].Text   =   "c ";
                        else   if   (GridView1.DataKeys[3].Value.ToString()   ==   "1 ")
                                row.Cells[2].Text   =   "d ";
                        else   row   .Cells   [2].Text   =   "e ";
        }

运行时,第一条if可以正常运行并赋值,到了第三行的时候,就会出现如下错误提示:

索引超出范围。必须为非负值并小于集合大小。
参数名:   index  
说明:   执行当前   Web   请求期间,出现未处理的异常。请检查堆栈跟踪信息,以了解有关该错误以及代码中导致错误的出处的详细信息。  


异常详细信息:   System.ArgumentOutOfRangeException:   索引超出范围。必须为非负值并小于集合大小。
参数名:   index

请问datakeynames最多只能设置两个字段吗?google搜了下也没找到解决办法,语句都是copy的也不应该有问题啊。。

[解决办法]
一个较优雅的GridView隐藏列取值解决方案
分类:技术专区时间:2006-7-28 21:49:22作者:supNate在Asp.net 2.0中增加了一个新的数据绑定控件:GridView,其目的用来取代Asp.net1.x中的DataGrid控件,但有一点很不爽的是,如果把某列设置为visible=false,则不会进行数据绑定,也就是说无法直接从GridView中取到这个列内的文本。
这一功能在DataGrid时代几乎是必须的,在对列表进行批量选中操作时非常有用(比如批量删除),隐藏列通常用于存储DataGrid行对应数据记录的关键字的值,而现在在GridView中却行不通,着实令一大批人头疼不已,网上也有了其解决方案,其中一个如下,其原理是在行创建时设置其css样式为不可见,这样可以避免直接设置列的visible=false带来的数据不绑定问题:


void GridView1_RowCreated(object sender, GridViewRowEventArgs e)
{
//让索引为0的列不可见,实际上是产生的css代码
e.Row.Cells[0].Visible = false;
//other code if neccecary
}
个人认为此方法不够优雅,Asp.net 1.x年代本人就尽量避免使用事件,宁可在数据源DataTable中做循环遍历来进行一些或烦或简的处理。一来因为vs2003对web标准支持欠佳,而我习惯于在Html源码模式下工作,所以为DataGrid添加一个事件是极其麻烦的事情;二来因为其性能我也不大放心,毕竟每一行都要触发一次事件。因而在GridView中仍然不喜欢事件,而且即使vs2005对web标准的支持大大改善,但添加一个事件容易,删除一个事件还是要在两个文件中进行手动删除才能同步,比较麻烦。

就事论事,回到标题,现提供我对这个问题的解决方案,基本思想仍然是用css使得单元格不可见,而不妨碍它的数据绑定,但我的方法却不需要在cs文件中多加一行代码,其思路如下:
(1)设置一个css类:


.hidden { display:none;}

在web标准横行的现在,我想为每个aspx链接一个common.css是基本的素质,呵呵
(2)随后在GridView的列编辑对话框中,对需要进行隐藏的列进行设置,分别设置FootStyle,HeaderStyle,ItemStyle的CssClass属性为“hidden”
Ok,这样我们就实现了隐藏列的目的,同时又能保证对其进行数据绑定。

好了,看到这里,如果你有所收获,并很高兴的马上赶回去,为你的GridView添加此设置,避免了使用事件来隐藏列,并实现了批量删除的功能。那你就大错特错了,呵呵
很可惜的是,在网上看到很多人关于GridView的这个功能的讨论,很大一部分人都是为了这个功能而来的。

是的,在DataGrid中,要实现这个功能,隐藏列来存储键值是必须的,甚至是一个初学者需要摸索才能知道的技巧。然而现在GridView是用来替代DataGrid的,微软所作的考虑更加周全。针对DataGrid无法提供行主键的问题,它提供了两个全新的属性:DataKeys和DataKeyNames!其SDK中的描述如下:
DataKeyNames:获取或设置一个数组,该数组包含了显示在 GridView 控件中的项的主键字段的名称。
DataKeys:获取一个 DataKey 对象集合,这些对象表示 GridView 控件中的每一行的数据键值。

看到这里,也许你会有所明白,针对批量选中操作的问题,我们有了新的方案,现在来看一个简单的实现,假设主键字段是id:

//设置主键字段名称数组,可以多个字段,
//你也可以在设计器中直接设置主键字段,多个字段用逗号隔开
GridView1.DataKeyNames = new string[] { "id " };
这样,当进行数据绑定时,GridView会自动用键值填充DataKeys集合,从而在绑定或者回传后可以通过DataKeys集合来获取某一行的键值,例如假设想获取第i行的id键值,其代码如下:

//获取第i行的id键值,注意该索引即行的索引,从header到footer都算在内
string id=GridViews1.DataKeys[i][ "id "].ToString();
//通过键值对数据进行处理……
由此可见,GridView提供了新的机制来绑定额外的数据到每一行。这使得可以完全放弃原来DataGrid通过隐藏列来绑定键值的做法,显然,现在的方案要优雅的多。当然,如果你实在需要在GridView中使用隐藏列并能够进行取值,我上面的方法不防一试,虽然我很难想到有这样的需求^_^

热点排行