views:

93

answers:

2

Hi Gang,

I've run into a bit of a funny one and thought it was worth posting:

I'm using an Advanced Data Grid in a case where I've got to set the data provider at runtime using hierarchical data. The adobe docs don't really cover this kind of thing (at least not at the level I could dig to).

Has anyone run into this before?

The only thing I could come up with was a bit hackish and seems to introduce some strange behavior with the disclosure icons of the advanced grid. I've included a test case below:

advancedDataGridProblem.as:

 import mx.collections.ArrayCollection;

 public var dataProvider:ArrayCollection = new ArrayCollection([{label:"item1"},
             {label:"item2", children:[{label:"subItem1"},{label:"subItem2"},
             {label:"subItem3"}]},
             {label:"item3"}]);

 public function init():void{
      //using callLater to ensure that the grid has been created before setting DP
      this.callLater(setDataProvider,[dataProvider]);
 }

 public function setDataProvider(list:ArrayCollection):void{
      heirData.source = list;
 }

and the mxml:

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="init()">
     <mx:Script source="advancedDataGridProblem.as"/>


  <mx:AdvancedDataGrid id="advDG" width="100%">

   <mx:columns>
        <mx:AdvancedDataGridColumn headerText="What the heck?"/>
        <mx:AdvancedDataGridColumn headerText="Label" dataField="label"/>
        <mx:AdvancedDataGridColumn headerText="Column 2"/>
        <mx:AdvancedDataGridColumn headerText="Column 3"/>
   </mx:columns>

   <mx:dataProvider>
        <mx:HierarchicalData id="heirData"/>
   </mx:dataProvider>
 </mx:AdvancedDataGrid>

</mx:Application>

As you can see when you run the test application, the icons which should show up in the Label column are actually placed in the "What the heck?" column. If you drag the Label column over and attempt to swap it with the "What the heck?" column, the icons remain where they are, but miraculously, the labels that were previously left aligned for the Label column are now formatted appropriately for the icons. Dragging the Label column out of slot one will revert the grid to it's original condition.

This one's a little above my head - anyone have any suggestions?

Ideally, I'd like to get around this hack all together and just assign the dataProvider as per usual at run-time.

Thanks in advance!

I'll be filing a bug report with adobe about this one shortly, and will throw the link into a comment.

A: 

Well..

After a weekend to give my head a good shake and a pair of fresh eyes today, I've found a solution for the 'easy' part of my question.

To set the AdvancedDataGrid's dataProvider directly is much simpler than I had originally thought; you just need to cast the ArrayCollection as HierarchicalData. To be honest, I had tried this before, but was spelling Hierarchical incorrectly.. facepalm.

Anyhow, advancedDataGridProblem.as should be changed to:

import mx.collections.ArrayCollection;
import mx.collections.HierarchicalData;

public var dataProvider:ArrayCollection = new ArrayCollection([{label:"item1"},
                                                                {label:"item2", children:[{label:"subItem1"},{label:"subItem2"},
                                                                {label:"subItem3"}]},
                                                                {label:"item3"}]);

public function init():void{
    //using callLater to ensure that the grid has been created before setting DP
    this.callLater(setDataProvider,[dataProvider]);
}

public function setDataProvider(list:ArrayCollection):void{
    advDG.dataProvider = new HierarchicalData(list);
}

The declaration of the dataProvider in the mxml can also be removed:

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="init()">
 <mx:Script source="advancedDataGridProblem.as"/>


<mx:AdvancedDataGrid id="advDG" width="100%">

 <mx:columns>
    <mx:AdvancedDataGridColumn headerText="What the heck?"/>
    <mx:AdvancedDataGridColumn headerText="Label" dataField="label"/>
    <mx:AdvancedDataGridColumn headerText="Column 2"/>
    <mx:AdvancedDataGridColumn headerText="Column 3"/>
 </mx:columns>
 </mx:AdvancedDataGrid>

</mx:Application>

Running this code, you can still see the disclosure icons in the wrong column, but at least the 'hackish' solution of setting the grid's dataProvider in mxml is removed. Doing this also allows proper validation and the grid's display. Setting the grid's dataProvider allows proper display validation, where apparently setting it's dataProvider's hierarchical data's source does not invoke those same validation methods, requiring the user to resize the grid or the programmer to force validation somehow (which for the life of me I couldn't do).

I'll keep you posted on the disclosure icon issue. In the mean time, I expect that locking the first column and using it solely for those icons will do just fine in my application. I may even turn this 'flaw' into a 'feature' :P

Cheers!

[EDIT]

Another method that allows for even easier implementation and less business logic when using bound data is such:

advancedDataGridProblem.as:

import mx.collections.ArrayCollection;
import mx.collections.HierarchicalData;

public var dataProvider:ArrayCollection = new ArrayCollection([{label:"item1"},
                                                                {label:"item2", children:[{label:"subItem1"},{label:"subItem2"},
                                                                {label:"subItem3"}]},
                                                                {label:"item3"}]);

The mxml:

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
 <mx:Script source="advancedDataGridProblem.as"/>


<mx:AdvancedDataGrid id="advDG" width="100%">

 <mx:columns>
    <mx:AdvancedDataGridColumn headerText="What the heck?"/>
    <mx:AdvancedDataGridColumn headerText="Label" dataField="label"/>
    <mx:AdvancedDataGridColumn headerText="Column 2"/>
    <mx:AdvancedDataGridColumn headerText="Column 3"/>
 </mx:columns>

 <mx:dataProvider>
     <mx:HierarchicalData source="{dataProvider}"/>
 </mx:dataProvider>

 </mx:AdvancedDataGrid>

</mx:Application>

This approach circumvents possible issues regarding having to manually invalidate and validate the grid's list, display list, etc. after setting the grid's dataProvider in ActionScript. My one minor reservation using this method is that as this creates a one-way binding in flex 3, I'm unsure as to whether or not I'll be able to use the HierarchicalData object's methods to alter the bound ArrayCollection. That said, I haven't poked around in the source for the HierarchicalData or AdvancedDataGrid, but I wouldn't doubt that they do alter the source directly. I'll post results as they come.

Cheers!

SpaceCase
A: 

To resolve the disclosure icon issue noted above, you can specify the AdvancedDataGrid's "treeColumn" property, passing the id of the column which your tree data should be in.

Apparently I was blind the other day looking at the livedocs.

Cheers!

SpaceCase