I have a DataGrid and I set the DataProvider to my data. When my data changes the DataGrid loses the selected row and the scroll bar jumps back to the top. How do I maintain the selection and scroll position?
If you just want to maintain position:
in whatever function is changing the data, first capture the selected index
var myidx:int = new int(myDG.selectedIndex);
and the scroll position
var myVertPos:int = new int(myDG.verticalScrollPosition);
run the code that changes the data then do the above steps backwards:
myDG.selectedIndex = myidx;
myDG.verticalScrollPosition = myVertPos;
Oh and you will probably want to do a check to make sure that the selected index is not over the length of items now in your DG and select the last one if it is. In my experience setting the vertical scroll position greater than the max just results in scrolling to the max.
There is a way. you need to extend the DataGrid Class and add a String property uniqueIdField.
Set the vaule of uniqueIdField to a property of the objects in the dataset that is unique.
then override the set dataProvider method as below: this will work if the columns are not sorted. FIXED*I now have the issue that when the column is sorted the correct row hightlights but the scrollbar does not mve to the value (as one of its properties that affect the sort has changed).*
The code below set the the scrollbar to the correct position.
override public function set dataProvider(value:Object):void { var vScroll:int = 0; //check to see if we reselect previous selected item //and save current postion 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)
{
var currentObj:Object;
var found: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;
}
}
//notify that the item has been selected, found or null this.verticalScrollPosition = vScroll; dispatchEvent(new ListEvent(ListEvent.CHANGE));
}