当数据改变时,我如何在DataGrid中保持选择?

3

我有一个DataGrid,我将DataProvider设置为我的数据。当我的数据发生变化时,DataGrid会失去选定的行,并且滚动条会跳回顶部。如何保持选择和滚动位置?


您是否希望即使所选项目已更改,仍保留所选位置?还是希望保留所选项目,即使它在新位置? - invertedSpear
2个回答

8

如果您只想保持位置不变:

在更改数据的任何函数中,首先捕获所选索引。

var myidx:int = new int(myDG.selectedIndex);

滚动位置

var myVertPos:int = new int(myDG.verticalScrollPosition);

运行修改数据的代码,然后按照上述步骤倒序执行:
myDG.selectedIndex = myidx;
myDG.verticalScrollPosition = myVertPos;

噢,你可能想要进行检查,确保所选索引没有超过DG中现有项的长度,如果超过了,就选择最后一个。根据我的经验,将垂直滚动位置设置为大于最大值只会导致滚动到最大值。


如果新的dataProvider将selectedItem放在不同的索引中,那么它会如何工作呢? - Robusto
这是为什么我试图询问OP的意图(维护项目还是维护索引),我认为您可以使用类似var myItem:Object = myDG.selectedItem;myDG.selectedItem = myItem;的东西来维护项目,但是我不确定如何在没有进行大量测试的情况下解决它。然后,您需要找到滚动位置... 维护项目要复杂得多 :-) - invertedSpear
这似乎运行良好,因为我的列表中的项目数量没有改变,只是相关数据。谢谢。 - Roland Rabien
难道整个重点不就是数据(例如从数据库中获取的数据)可以被更改吗?我发现最好的方法是保持一个与选择同步的selectedId变量,然后在数据源上挂一个更改观察器,并通过迭代所有行来重置选择。待办事项:如何保证更改观察器仅在数据在网格中刷新后运行,因此可能有更好的方法。 - FredV
1
invertedSpear:这不会起作用,因为AS3有一个很大的缺点,即不能重载并在用户定义的类上使用equals方法(就像在Java或任何其他好的语言中一样)。selectedItem = myItem不起作用,因为Flex比较对象的引用(在重新加载后已更改)。 - FredV
谢谢FredV,我一直担心这个问题,所以没有将它发布为答案 :) 我知道维护索引是简单的方法,听起来OP已经从中得到了想要的结果,但我很好奇如何维护一个项目。我喜欢保留全局变量的简单性。 - invertedSpear

2
有一个方法。您需要扩展DataGrid类并添加一个字符串属性uniqueIdField。
将uniqueIdField的值设置为数据集中对象的某个唯一属性。
然后按如下所示覆盖set dataProvider方法: 如果列未排序,则此方法可行。已修复*现在我的问题是,当列被排序时,正确的行会高亮显示,但滚动条不会移动到该值(因为影响排序的其属性之一已更改)。
以下代码将滚动条设置为正确位置。

override public function set dataProvider(value:Object):void { var vScroll:int = 0; //检查是否重新选择先前选择的项目 //并保存当前位置 if(uniqueIdField.length > 0 && selectedItem != null) { uniqueIdData = this.selectedItem[uniqueIdField]; vScroll = this.verticalScrollPosition; }

super.dataProvider = value;

        if(uniqueIdField.length > 0 
        && uniqueIdData != null
        && selectedItems.length <= 1)

{
当前对象:Object类型;
是否找到:Boolean类型,初始值为false;

if(dataProvider is ArrayCollection)
{

 //find object in dataprovider
 for(var i:int=0; i < dataProvider.length; i++)
 {
  currentObj = dataProvider.getItemAt(i);
  if(currentObj[uniqueIdField] == uniqueIdData)
  {
   this.selectedItem = currentObj;
   found = true;
   vScroll = this.selectedIndex;
   break;

  }
 }

 if(!found)
 {
  this.selectedItem = null;
  uniqueIdData = null;
 }


}

//通知已选择、找到或为空的项目 this.verticalScrollPosition = vScroll; dispatchEvent(new ListEvent(ListEvent.CHANGE));

}


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接