Monday, June 20, 2011

HierarchicalCollectionView updateLength discovery

So, in another round of heavy debugging - I came across an an anomaly, which really is just a difference between what the developer thought would happen, and how I chose to implement a feature.

In the HierarchicalCollectionView, on the collectionChange event the length of the collection gets updated for nearly all CollectionChangeKinds except for UPDATE. Now this makes sense, changing a property shouldn't result in a change of length (like adding or removing children).

Unfortunately, the way that I a structured our application was that the items that needed to expand (ie have children) where flat, not hierarchical. So my solution was to toggle a property on the item to indicate that it had children. When I applied the same interface to the grouping collections (so that I could use the same framework for expanding and collapsing), I discovered that the length wasn't being recalculated and thus scrolling was throw off.

Annoyingly, much of the calculate length features in HierarchicalCollectionView are private. So here is a solution that I put in place, but it isn't very pretty:

class HierarchicalCollectionViewWithUpdateListeners extends HierarchicalCollectionView
{
 
 private var myLength:int
 private const NO_LENGTH:int  = -1
 public function HierarchicalCollectionViewWithUpdateListeners(hierarchicalData:IHierarchicalData=null, argOpenNodes:Object=null)
 {
  super(hierarchicalData, argOpenNodes);
 }
 
 
  public override function collectionChangeHandler(event:CollectionEvent):void
  {
   super.collectionChangeHandler(event);
   myLength = NO_LENGTH;
   if (event.kind == CollectionEventKind.UPDATE)
   {
    myLength = calculateLength();
   }
   
  }

  
  public override function get length():int
  {
   var origLen:int = super.length;
   if (myLength != NO_LENGTH)
   {
    return myLength;
   }
   else
   {
    return origLen; 
   }
  }


}

7 comments:

  1. Hi Drew,

    could you please explain how to use your class with an AdvanceDatagrid??

    Many thanks in advance.

    ReplyDelete
    Replies
    1. Alejandro,

      It doesn't directly apply to the ADG, but it is related as this would be a potential dataprovider.

      The above class extends HierarchicalCollectionView, which can be a dataprovider for the AdvancedDataGrid.

      Delete
    2. Also, it only applies if you will be changing a property, and then that property affects the number of children that that object has.

      Delete
  2. Hi Drew,

    many thanks for the advice. I'm using an ArrayCollection as a dataprovider for the tree. Every item is an object with several fields. At this point, the own component is setting the HierarchicalCollectionView. I was trying to capture this structure and convert it to your class. Is it possible to convert the ArrayCollection to your class, or even the HierarchicalCollectionView set by the component itsef?

    Many thanks for your help. I do really need this.

    ReplyDelete
  3. I almost forgot. I'm modifying the rowCount property of the ADG, I need to adapt the number of rows to the number of items present in the tree. I mean, every time a node is expande or collapsed I need to add rows or remove rows. It's a requirement for me not having empty rows.

    ReplyDelete
  4. Alejando. So you are using an ArrayCollection with a defined children property to represent the HierarchicalData? I'm not convinced that my solution above is still your right solution. Is each field of your item a child? What does your hierarchy look like?

    if you prefer you can contact me at
    dshefman squaredi com

    ReplyDelete
  5. trying to be tricky with my address

    dshefman [at /] squaredi [dot /] com

    ReplyDelete