1

I am working on an indent and outdent for the advanced datagrid. I have a set of functions which work when operating on the underlying data fine, but which throw "Error: Bookmark no longer valid" when operating on the selected items of the datagrid.

When I run this code it runs fine:

indentLeaf(l5)
outdentLeaf(l4)

But this code fails:

adg.selectedItem = l5
indentLeaf(adg.selectedItem as Leaf)
adg.selectedItem = l4
outdentLeaf(adg.selectedItem as Leaf)

The code does not fail in all instances, only for some configurations of the data grid data tree.

The code needs to be run in the debugger version of the flash player if you want to see the error thrown. I have cut and pasted the error I get into the text area for reference as well as below.

The code in the toy app seems to recover ok when the exception is thrown, but in my larger app it leads to hard crashes.

Example code can be found here with view source turned on: http://www.crcarlson.com/adg/ADGArrayCollectionUpdate.swf

To create the error, reset the tree and then click "indent/outdent2"

I would appreciate any suggestions on how to get around this.

The full stack trace looks like this:

Error: Bookmark no longer valid.
at ListCollectionViewCursor/seek()[E:\dev\4.x\frameworks\projects\framework\src\mx\collections\ListCollectionView.as:2417]
at mx.collections::HierarchicalCollectionViewCursor/get current()[E:\dev\4.x\frameworks\projects\datavisualization\src\mx\collections\HierarchicalCollectionViewCursor.as:220]
at mx.collections::HierarchicalCollectionViewCursor/collectionChangeHandler()[E:\dev\4.x\frameworks\projects\datavisualization\src\mx\collections\HierarchicalCollectionViewCursor.as:1143]
at flash.events::EventDispatcher/dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()
at mx.collections::HierarchicalCollectionView/nestedCollectionChangeHandler()[E:\dev\4.x\frameworks\projects\datavisualization\src\mx\collections\HierarchicalCollectionView.as:1595]
at flash.events::EventDispatcher/dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()
at mx.collections::ListCollectionView/dispatchEvent()[E:\dev\4.x\frameworks\projects\framework\src\mx\collections\ListCollectionView.as:1024]
at mx.collections::ListCollectionView/handlePropertyChangeEvents()[E:\dev\4.x\frameworks\projects\framework\src\mx\collections\ListCollectionView.as:1433]
at mx.collections::ListCollectionView/listChangeHandler()[E:\dev\4.x\frameworks\projects\framework\src\mx\collections\ListCollectionView.as:1300]
at flash.events::EventDispatcher/dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()
at mx.collections::ArrayList/internalDispatchEvent()[E:\dev\4.x\frameworks\projects\framework\src\mx\collections\ArrayList.as:673]
at mx.collections::ArrayList/itemUpdateHandler()[E:\dev\4.x\frameworks\projects\framework\src\mx\collections\ArrayList.as:704]
at flash.events::EventDispatcher/dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()
at Leaf/dispatchChildrenChanged()[C:\adobeFlexTraining\_workspace\ADGArrayCollectionUpdate\src\Leaf.as:119]
at Leaf/addChildAt()[C:\adobeFlexTraining\_workspace\ADGArrayCollectionUpdate\src\Leaf.as:63]
at Leaf/move()[C:\adobeFlexTraining\_workspace\ADGArrayCollectionUpdate\src\Leaf.as:96]
at ADGArrayCollectionUpdate/outdentLeaf()[C:\adobeFlexTraining\_workspace\ADGArrayCollectionUpdate\src\ADGArrayCollectionUpdate.mxml:86]
at ADGArrayCollectionUpdate/IO2_clickHandler()[C:\adobeFlexTraining\_workspace\ADGArrayCollectionUpdate\src\ADGArrayCollectionUpdate.mxml:113]
at ADGArrayCollectionUpdate/__IO2_click()[C:\adobeFlexTraining\_workspace\ADGArrayCollectionUpdate\src\ADGArrayCollectionUpdate.mxml:183]
crcarlson
  • 189
  • 1
  • 11
  • I've got the same problem, and it's a show stopper for my application. Did you make any progress on this? As soon as I find something, I'll post it here.. Cheers. – Tom Feb 28 '11 at 09:27

3 Answers3

4

I just found a workaround for this bug (I am using SDK 3.5 but I guess a 4.1 fix would be very much the same). The problem lies within the "current()" getter of the HierarchicalCollectionViewCursor class.

It doesn't catch the CursorError that's caused by an invalid bookmark.

Step 1 is to create a better cursor class:

public class HierarchicalCollectionViewCursor2 extends HierarchicalCollectionViewCursor
{
    public function HierarchicalCollectionViewCursor2(collection:HierarchicalCollectionView, model:ICollectionView, hierarchicalData:IHierarchicalData)
    {
        super(collection, model, hierarchicalData);
    }


    override public function get current() : Object
    {
        // original HierarchicalCollectionViewCursor class fails to catch the "bookmark no
        // longer valid" Error, which is thrown as a CollectionViewError instance in ListCollectionView,
        // but transformed to a CursorError within the same class
        try {
            var result:Object = super.current;
        }
        catch (e:CursorError) {
            result = null;
        }

        // done
        return result;
    }
}

Step 2 is to create a HierarchicalCollectionView class, which returns that new cursor:

use namespace mx_internal;

public class HierarchicalCollectionView2 extends HierarchicalCollectionView
{
    public function HierarchicalCollectionView2(hierarchicalData:IHierarchicalData=null, argOpenNodes:Object=null)
    {
        super(hierarchicalData, argOpenNodes);
    }


    override public function createCursor() : IViewCursor
    {
        return new HierarchicalCollectionViewCursor2(this, treeData, this.source);
    }
}

Step 3 is to actually use that new HierarchicalCollectionView2 class as your data-provider.

var itemsAC:ArrayCollection = new ArrayCollection();
// add items etc
this.adgDataProvider = new HierarchicalCollectionView2(new HierarchicalData(itemsAC));

Now you would think that all is well BUT the drama wouldn't be complete without another annoying Flex-SDK bug. In this case its:

https://bugs.adobe.com/jira/browse/FLEXDMV-1846

So, Step 4 is to subclass the AdvancedDataGrid component as described in the bug issue.

That's it -- works for me!

Tom
  • 1,965
  • 3
  • 25
  • 33
  • Awesome, thank you for taking the time to post this answer. I thought I was going crazy there for a while... – crcarlson Mar 01 '11 at 00:45
  • Awesome indeed - this has been a pain when used with updating filters. Technically if this is all you do with the HCV2, then the ADG override isn't necessary since it extends the original HCV, but it's a problem if you roll your own from another super class. – Mike Petty Nov 02 '12 at 22:22
  • The link to FLEXDMV-1846 is broken. Was the bug fixed? If not, what is it that needed to be done? – Florian F Jul 17 '15 at 14:38
0

This Exeption may hapen in Flex AdvancedDatagrid with HierarchicalData. When items are added to Dataprovider it notifies the datagrid . the datagrid receives colection change events each time items are added to it.then some Datagrid internal can be messed up . You could disable the automatic ArayCollecion refresh :

    dataprovider.disableAutoUpdate();

and when you datagrid is ready to use refresh datagrid rendering :

    if (advancedDataGrid) {
            advancedDataGrid.invalidateList();
            advancedDataGrid.invalidateDisplayList();
            advancedDataGrid.expandAll();
        }

I hope this will help.

Sami Jmii
  • 460
  • 7
  • 17
0

Sami was right about the internals (of HierarchicalCollectionViewCursor) getting messed up. This was one of the most long-standing bugs in the Flex framework. It was recently documented - and fixed - at FLEX-34119 and all its linked tickets. It should be available in Flex SDK 4.14, which means that no workaround will be needed from that point onward.

Community
  • 1
  • 1
user166267
  • 51
  • 1
  • 7