Monday, January 26, 2009

Flex Advanced Data Grid collapses on refresh

I was having this problem with my Advanced Data Grid. Every time the data refreshed the whole thing collapsed, which isn't a good thing when users have drilled down 3 levels.

I know this is probably a bad way of doing this, but it is the only way I could get to work. All the examples I've seen of this say to just assign the saved openNodes Object to the openNodes property, like this...

myOpenNodes = new Object();
myOpenNodes = IHierarchicalCollectionView(myADG.dataProvider).openNodes

//refresh here

IHierarchicalCollectionView(myADG.dataProvider).openNodes = myOpenNodes;

but that doesn't work!!

Here is what I did:

On the refresh method set the following variables (these variables need to be accessible from all methods inside the component, so put them in your model or make them global, whatever). These variables hold the state of the ADG before the refresh.

//Object holding all currently open nodes
myOpenNodes = new Object();
myOpenNodes = IHierarchicalCollectionView(myADG.dataProvider).openNodes

lastSelectedItem = myADG.selectedItem;

lastScrollPosition = myADG.verticalScrollPosition;


This method loops through every item in the advanced data grid up to the depth you provide (here it is to the depth of 4). Then any time it finds an object that is also in the myOpenNodes object it adds to to an array that then is assigned to the ADG.openNodes property. In this example the property of the grid item I am using to compare is called "Group".

private function selectLastADGItem(evt:Event):void
{
//Array to assign to openNodes property
var savedNodesArray:Array = [];

for(var i:int=1; i<4; i++)
{
var dataCursor:IHierarchicalCollectionViewCursor = myADG.dataProvider.createCursor();

while (dataCursor.current)
{

for each ( var item:Object in myOpenNodes )
{
//Check if current item is in openNodes object
if ( item.Group == dataCursor.current.Group )
{
savedNodesArray.push(dataCursor.current);
}

//Check if current item is the last selected item
if ( item.Group == dataCursor.current.Group )
{
myADG.selectedItem = dataCursor.current;
}
}

dataCursor.moveNext();
}

myADG.validateNow();

//Assign new array to openNodes property IHierarchicalCollectionView(myADG.dataProvider).openNodes = savedNodesArray;

myADG.dataProvider.refresh();
}

//Move vertical scrollbar to last position
myADG.verticalScrollPosition = lastScrollPosition;

}

8 comments:

Chandra said...

Would you please post a sample mxml?
thank you

Ang said...

Hey Chandra,

I'm not sure what you need in regards to mxml, I don't have time to post an example just now, but I thought maybe if you were pressed for time you could check out: http://livedocs.adobe.com/flex/3/html/help.html?content=advdatagrid_06.html There are examples of Advanced Data Grids there. In addition to that I just used a button that called my method in this post to refresh the ADG.

Anonymous said...

Try this :

import mx.collections.HierarchicalCollectionView;


myOpenNodes:Array = new Array();
var HierColView:HierarchicalCollectionView = HierarchicalCollectionView(myADG.dataProvider);

for each ( var item:Object in HierColView.openNodes ) {
myOpenNodes.push(item);
};


myADG.dataProvider.openNodes = myOpenNodes;

Vijendra Babar said...

Hey, above mention solution is really cool!!

Its fairly simple & solves lots of problems.

santa said...

I tried the same but it doesnt work .. can anyone put some code snippet for the same ?

thanks for your help ..

Manuel Gaytán said...

Thank very much it was so useful, because my nodes are differents
memory instances after refresh, but I compare the identifier as you shown for restoring.

if( item.digito == dataCursor.current.digito ){ //Check if current item is in openNodes object
savedNodesArray.push(dataCursor.current);
}

Anonymous said...

Hi,

I did the same thing , I see the list of open nodes. But Tree still doesn't open , its in the colsed state. Any thoughts?

Thanks

Jalil Asghar said...

Thanks for the code!! It's been a God-send because I've been pulling my hair out trying out all sorts of combinations to get the node refresh working on my hierarchical ADG but nothing seemed to work quite right.

Your solution worked perfectly! Thank you.