It’s a best practice to size a Spark DataGrid’s columns with a typicalItem

Coming from Flex 3, if I wanted to set the size of my DataGrid columns to ensure that all of my data was displayed correctly, I would either set column widths with explicit values or percentages. In Flex 4, explicit width columns is no longer the recommended way of figuring out the size of columns according to Spark DataGrid’s architect Hans Muller who schooled me when I mentioned the need to fix a bug that involved explicit width columns.

By default, a DataGrid will use the first item in its dataProvider to determine the size of each column. This may not be what you want. If you specify a typicalItem on the DataGrid, the columns will be large enough to fit this item. This item does not need to be a part of your dataProvider.

Specifying explicit column widths can be problematic because the width can be invalidated by  a host of factors: implicit renderer changes, e.g. due to inherited styles, explicit renderer changes, margin/padding and other layout configuration changes, as well as text and text format localizations.  For all of these reasons, using the typicalItem is better.

In the following example, I have two DataGrids with the same data and columns. The first one specifies a typicalItem where the data includes the longest strings that I want to display in my columns. The second DataGrid uses no typicalItem and therefore sizes its columns using the first item of the dataProvider.

Sample application: TypicalItem_DataGrid_Example.swf

Sample MXML: TypicalItem_DataGrid_Example.mxml

If you change your typicalItem, you will need to call invalidateTypicalItem() notifying the DataGrid of this change.

Note, almost all of this information was compiled from picking the brain of Hans Muller, I hope I’ve accurately represented his thinking.

9 responses

  1. Hi. i’m trying to figure out the Spark DataGrid event lifecycle, and the lifecycle of the GridColumns. I have some items in a parent container that I want to size relative to the GridColumn widths. I’ve tried adding listeners to various events on the DataGrid, like UPDATE_COMPLETE, ADDED_TO_STAGE, etc., but it appears that the .width property of the grid columns is always NaN until you explicitly change the column’s width by dragging the header separator. The columns obviously have a width, because they’re being drawn on stage, but I can’t find a public property or method that exposes it. And since GridColumns aren’t even UiComponents, they don’t have a getExplicitOrMeasuredWidth method or anything. Any ideas?

    Thanks!

    Michael

  2. So, turns out that Grid has a public method, getColumnWidth(), which takes the column index as a parameter and returns the correct value. Keep in mind that the indexes change when you add or remove columns dynamically, so you’ll need to get the correct index before requesting the width. Also, if you change columns dynamically, you’ll want to call validateNow() on the DataGrid before doing anything with column widths, because otherwise the GridLayout’s set of columns will be out of sync with the Grid’s actual columns; see http://python.mmitd.com/bugs.adobe.com/jira/browse/SDK-29918

  3. Hi,

    best POG is:

    protected function group1_creationCompleteHandler(event:FlexEvent):void
    {
    dgEnderecos.addEventListener(ResizeEvent.RESIZE, onResizeDGEnderecos);
    }

    protected function onResizeDGEnderecos(event:ResizeEvent):void
    {
    gcLogradouro.grid.validateNow();
    callLater( resizeTILogradouro );
    }

    protected function resizeTILogradouro():void
    {
    tiLogradouroEndereco.width = gcLogradouro.grid.getColumnWidth(gcLogradouro.columnIndex);
    }

    dgEnderecos is my spark dataGrid.
    gcLogradouro is my gridColumn.

    Now is nice..

    Hug.

  4. Correcting,

    this works for my need:

    protected function group1_creationCompleteHandler(event:FlexEvent):void
    {
    resizeTILogradouro();
    resizeTIComplemento();
    dgEnderecos.addEventListener(ResizeEvent.RESIZE, onResizeDGEnderecos);
    }

    protected function onResizeDGEnderecos(event:ResizeEvent):void
    {
    gcLogradouro.grid.validateNow();
    callLater( resizeTILogradouro );
    callLater(resizeTIComplemento );
    }

    protected function resizeTILogradouro():void
    {
    tiLogradouroEndereco.width = (dgEnderecos.grid.getColumnWidth(gcLogradouro.columnIndex) -1 );
    }

    protected function resizeTIComplemento():void
    {
    tiComp.width = (dgEnderecos.grid.getColumnWidth(gcComplemento.columnIndex) -1 );
    }

    Hug.

  5. Sorry for the flood, just accept the first comment (POG hehe).

    I’m still changing.

  6. I have a related problem but do not find any solution since some month … maybe you know a solution?

    I use the following class to create datagrids by an external xml. Since Flex 3 (mx.datagrid) everything worked fine – I was able to define the typical width of a column dynamically. Since the spark datagrid its not working any longer … so all columns have the same width at start.

    Any idea if its possible to set the width dynamically?

    #########################################

    public function createColumns( cList:XML ):void{

    dgcArr = [];

    for( var i:int = 0; i < cList.children().length(); i++ ){

    dgcArr[i] = new GridColumn( cList.children()[i].@label );

    ( dgcArr[i] as GridColumn ).dataField = cList.children()[i].@data;

    ( dgcArr[i] as GridColumn ).width = int(cList.children()[i].@data);

    colsArr.addItem(dgcArr[i]);

    }

    this.dg.columns = colsArr;
    this.dg.validateNow();

    }

    ##########################################

    thanks in advance

    p.s. my SDK is 4.6.

  7. uups. forgot to check the “notify” Button …

  8. Senor Plankton | Reply

    This has to be one of the dumbest things I’ve ever heard!

    Why should the ability to dictate column widths be dependent upon arbitrary data?

    Like most of the spark controls this is next to useless and involves a huge amount of extra work to develop anything even remotely usable in the real world.

  9. Hello,
    If a control containing a spark DataGrid is added back to the display list, when it is first displayed the datagrid appears a couple of pixels (presumably however many columns are present?) wider than it is subsequently displayed at after the layout has ‘settled down’. This effect is very transient, but if the datagrid is set to 100% width, this behaviour seems to initiate an endless loop in the layout manager, resulting in uncontrollable & continued expansion of the containing parent control – everything just wanders off the rhs of the screen…
    Do you have any ideas? Do you think Hans Muller could help with this?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: