FineUI 官方论坛

标题: 有关grid的DataKeyNames [打印本页]

作者: 信徒    时间: 2012-5-11 15:36
标题: 有关grid的DataKeyNames
版本:3.1.5
发现个问题前台设置了 DataKeyNames
后台在RowDataBound 事件里用
DataKeys[e.RowIndex][0].ToString();
取值的时候,第一行没问题,第二行就报index出界了
算不算bug?

作者: support    时间: 2012-5-11 15:43
写例子
作者: 信徒    时间: 2012-5-11 15:50
support 发表于 2012-5-11 15:43
写例子

[attach]449[/attach]
还是刚才的那个小测试程序,加个段代码,麻烦看一下

作者: support    时间: 2012-5-11 17:46
信徒 发表于 2012-5-11 15:50
还是刚才的那个小测试程序,加个段代码,麻烦看一下

的确是这样的,不要行绑定时访问DataKeys属性,这会导致以后再次访问此属性时也出现问题,看下DataKeys的源代码就知道:
  1. public List<object[]> DataKeys
  2.         {
  3.             get
  4.             {
  5.                 if (_dataKeys == null)
  6.                 {
  7.                     _dataKeys = new List<object[]>(_rows.Count);

  8.                     for (int i = 0, count = _rows.Count; i < count; i++)
  9.                     {
  10.                         _dataKeys.Add(_rows[i].DataKeys);
  11.                     }
  12.                 }

  13.                 return _dataKeys;
  14.             }
  15.         }
复制代码

所以在你绑定第一行数据时,就创建了一个只有一个元素的列表,绑定第二行时没有重新创建,而是直接返回上次创建的列表,所以就出现索引超出的错误。还有你在行绑定时Alert也是不对的,这个函数会被调用多次(多少行数据调用几次)。


正确的做法看官方示例:http://demo.extasp.net/#/grid/grid_rowdatabound.aspx
  1. protected void Grid1_RowDataBound(object sender, ExtAspNet.GridRowEventArgs e)
  2.         {
  3.             // e.DataItem  -> System.Data.DataRowView 或者自定义类
  4.             // e.RowIndex -> 当前行序号(从 0 开始)
  5.             // e.Values -> 当前行每一列渲染后的 HTML 片段

  6.             DataRowView row = e.DataItem as DataRowView;
  7.             if (row != null)
  8.             {
  9.                 e.Values[4] = String.Format("{0} - RowDataBound", e.Values[4]);
  10.             }
  11.         }
复制代码

在行绑定时能够直接拿到本行的数据源,想要啥有啥。





作者: 信徒    时间: 2012-5-11 20:02
support 发表于 2012-5-11 17:46
的确是这样的,不要行绑定时访问DataKeys属性,这会导致以后再次访问此属性时也出现问题,看下DataKeys的 ...

你给的方法确实也是一种替代方法,但是有时候某些值是不绑定到grid上去的,但是在后台绑定的时候又要作为一个判断条件,就需要访问原始的绑定源去取值了,虽然可以绕过这个问题,但是总是有些不方便的,原始的gridview是支持这个功能的,能不能修改下也支持呢。那个alert方法是我测试的时候忘了注释掉了,不好意思。

作者: support    时间: 2012-5-11 20:27
信徒 发表于 2012-5-11 20:02
你给的方法确实也是一种替代方法,但是有时候某些值是不绑定到grid上去的,但是在后台绑定的时候又要作为 ...

哦,回头我试下,应该尽量和asp.net控件保持一致
作者: 信徒    时间: 2012-5-11 20:43
support 发表于 2012-5-11 20:27
哦,回头我试下,应该尽量和asp.net控件保持一致

public List<object[]> DataKeys
        {
            get
            {
                if (_DataKeys== null)
                {
                    _dataKeys = new List<object[]>(_rows.Count);
                    for (int i = 0, count = _rows.Count; i < count; i++)
                    {
                        _dataKeys.Add(_rows.DataKeys);
                    }
                }
elese
{
for (int i = DataKeys.count, count = _rows.Count; i < count; i++)
{
_dataKeys.Add(_rows.DataKeys);
}
}
                return _dataKeys;
            }
        }
如果不为null的话,就增加从现有DataKeys 个数往后的?
你觉得这样可以吗?

作者: sanshi    时间: 2012-5-12 18:43
信徒 发表于 2012-5-11 20:43
public List DataKeys
        {
            get

太棒了,你这种做法应该就是Asp.Net的GridView的做法,刚才调试时发现,当我第5次进入GridView1_RowDataBound时,GridView1.DataKeys的个数也是5。
[attach]462[/attach]

下个版本会加上你的这个更新。
作者: xyong    时间: 2012-7-11 14:11
本帖最后由 xyong 于 2012-7-11 14:47 编辑

7#楼这个方法不行啊,删除后再绑定时,仍会出错。3.1.7和3.1.8.2版都存在这个问题
作者: xyong    时间: 2012-7-11 14:14
本帖最后由 xyong 于 2012-7-11 14:48 编辑

多行数据,删除一行数据并重新绑定,在RowDataBound 事件里用DataKeys[e.RowIndex][0]访问了已经删除的那行数据,引发脏读。猜测原因是grid的第一行数据绑定前没有清空DataKeys的数据。从上面的定义上看,集合数量只增不减,感觉grid的DataKeys属性太不可信赖了,建议不仅RowDataBound 事件里不要用它,其它地方也不要用它,用就用grid的Rows[e.RowIndex].DataKeys[0]方式





欢迎光临 FineUI 官方论坛 (https://fineui.com/BBS/) Powered by Discuz! X3.4