Flex – Problem with auto resizing datagrid

apache-flex

I'm trying to create a datagrid which will resize vertically to ensure all the renderers are displayed in full. Additionally,

  • Renderers are of variable height
  • Renderers can resize themselves

Generally speaking, the flow of events is as follows :

  • One of the item renderers resizes itself (normally in response to a user click etc)
  • It dispatches a bubbling event which the parent datagrid picks up
  • The DataGrid attempts to resize to ensure that all renderers remain visible in full.

I'm currently using this code within the datagrid to calculate the height:

height = measureHeightOfItems(0, dataProvider.length ) + headerHeight;

This appears to get an incorrect height. I've tried a number of variations including callLater ( to ensure the resize has completed so measure can work correctly), and overriding meausre() and calling invalidateSize() / validateSize(), but neither works.

Below are 3 classes which will illustrate the problem. Clicking the button in the item renderers resizes the renderer. The grid should also expand so that all of the 3 renderers are shown in their entirety.

Any suggestions would be greatly appreciated.

Regards

Marty

DataGridProblem.mxml (Application file)

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical"
    xmlns:view="view.*">
    <mx:ArrayCollection id="dataProvider">
        <mx:String>Item A</mx:String>
        <mx:String>Item B</mx:String>
        <mx:String>Item C</mx:String>
    </mx:ArrayCollection>
    <view:TestDataGrid
        id="dg" 
        dataProvider="{ dataProvider }"
        width="400">
        <view:columns>
            <mx:DataGridColumn dataField="text" />
            <mx:DataGridColumn itemRenderer="view.RendererButton" />
        </view:columns>
    </view:TestDataGrid>
</mx:Application>

view.TestDataGrid.as

package view
{
    import flash.events.Event;

    import mx.controls.DataGrid;
    import mx.core.ScrollPolicy;

    public class TestDataGrid extends DataGrid
    {
        public function TestDataGrid()
        {
            this.verticalScrollPolicy = ScrollPolicy.OFF;
            this.variableRowHeight = true;
            this.addEventListener( RendererButton.RENDERER_RESIZE , onRendererResize );
        }
        private function onRendererResize( event : Event ) : void
        {
            resizeDatagrid();
        }
        private function resizeDatagrid():void
        {
            height = measureHeightOfItems(0, dataProvider.length ) + headerHeight;
        }
    }
}

view.RendererButton.mxml

<?xml version="1.0" encoding="utf-8"?>
<mx:HBox xmlns:mx="http://www.adobe.com/2006/mxml">
    <mx:Button width="50" height="50"
        click="onClick()" />

    <mx:Script>
        <![CDATA[

            public static const RENDERER_RESIZE : String = "resizeRenderer";
            private function onClick() : void
            {
                this.height += 20;
                dispatchEvent( new Event( RENDERER_RESIZE , true ) );
            }
        ]]>
    </mx:Script>
</mx:HBox>

Best Answer

You can achieve this goal with the AdvancedDataGrid using the following code. If you remove the this.headerHeight, it works for List as well, which makes me believe it should work for the regular old DataGrid.

  override protected function measure():void
  {
   super.measure();

   if ( this.dataProvider )
   {
    var newHeight : int = measureHeightOfItems( 0, this.dataProvider.length ) + this.headerHeight;

    this.minHeight = newHeight;
    this.height = newHeight;
   }
  }
Related Topic