Locking columns in a horizontally scrolling DataGrid control

The following is an example of locking a fixed number of columns in a horizontally scrolling DataGrid control. Although this tip probably has little to no use if all your data fits comfortably in a data grid, it can be invaluable if you have a lot of columns and need to scroll horizontally as well as vertically.

Full code after the jump.

View MXML

<?xml version="1.0" encoding="utf-8"?>
<!-- http://blog.flexexamples.com/2007/08/15/locking-columns-in-a-horizontally-scrolling-datagrid-control/ -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
        layout="vertical"
        verticalAlign="middle"
        backgroundColor="white">

    <mx:DataGrid id="dataGrid"
            lockedColumnCount="1"
            horizontalScrollPolicy="on"
            width="300">
        <mx:columns>
            <mx:DataGridColumn dataField="@name" headerText="Name:" />
            <mx:DataGridColumn dataField="@colA" headerText="Column A:" />
            <mx:DataGridColumn dataField="@colB" headerText="Column B:" />
            <mx:DataGridColumn dataField="@colC" headerText="Column C:" />
        </mx:columns>
        <mx:dataProvider>
            <mx:XMLList>
                <item name="User 1" colA="1.A" colB="1.B" colC="1.C" />
                <item name="User 2" colA="2.A" colB="2.B" colC="2.C" />
                <item name="User 3" colA="3.A" colB="3.B" colC="3.C" />
                <item name="User 4" colA="4.A" colB="4.B" colC="4.C" />
                <item name="User 5" colA="5.A" colB="5.B" colC="5.C" />
                <item name="User 6" colA="6.A" colB="6.B" colC="6.C" />
                <item name="User 7" colA="7.A" colB="7.B" colC="7.C" />
                <item name="User 8" colA="8.A" colB="8.B" colC="8.C" />
            </mx:XMLList>
        </mx:dataProvider>
    </mx:DataGrid>

</mx:Application>

View source is enabled in the following example.

14 thoughts on “Locking columns in a horizontally scrolling DataGrid control

  1. I see how the column is locked. Is there a way to not have the scrollbar under the first column so the scrollbar component does not span the whole datagrid but just the columns that can scroll? This would be better for the user.

    Thanks

    1. I may be horribly late, but just in case anyone else is looking out for the same problem, this is how i did it.

      Worked well for me so far:

      override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void{
      super.updateDisplayList(unscaledWidth,unscaledHeight);
      if(lockedColumnCount)
      {
      var xPos:int=lockedColumnContent.width
      var yPos:int=horizontalScrollBar.y;
      var scrollWidth:int=horizontalScrollBar.width;
      horizontalScrollBar.width=scrollWidth-xPos; horizontalScrollBar.move(xPos,yPos);
      }
      }

  2. George Smith,

    I don’t know of an easy way to accomplish that without probably subclassing the DataGrid control and writing in the logic. You could try asking on Flexcoders and somebody there may have a better idea.

    If you think this is a worth enhancement request, you can file a bug/ecr at http://bugs.adobe.com/flex/ against the Flex SDK and select “Component: DataGrid”.

    Peter

  3. Is there a way to make column C on the example swf file not to resize and occupy the whole unfreeze section?

  4. RE: “Is there a way to remove that black vertical grid line. Tried a number of ways, sounds impossible.”

    Create a class as below:

    package
    {
        import mx.skins.halo.DataGridHeaderSeparator;
    
        public class DataGridHeaderSeparator extends mx.skins.halo.DataGridHeaderSeparator
        {
            override public function get measuredWidth():Number
            {
                return 0;
            }
    
            override public function setActualSize(newWidth:Number, newHeight:Number):void
            {
                graphics.clear();
            }
        }
    }
    

    Then in your DataGrid params use:

    verticalLockedSeparatorSkin="DataGridHeaderSeparator"
    

    That should do the trick :)

    Cheers,

    Simon

    newtriks dot com

    1. Sorry ’bout that. I learned that the columns with indexes that are lower than the value remain fixed in view.
      Thanks.

  5. Hi Peter,
    Let me first tell you that you have a great website going here. I constantly refer to it if I encounter any issues related to flex. With that being said, I have an itemrenderer and an itemeditor in a datagrid whose locked column count is set to 2. Within the datagrid I have a column whose text can be longer than the column width, the itemrenderer in this case is a Label and i set its percentWidth to 100, minWidth to 0 and trucateToFit property to true. The text displays fine with … , but after I edit another column I get the error below. If I remove that column though I do not get the error. Would you have any pointers as to what the issue might be?
    TypeError: Error #1009: Cannot access a property or method of a null object reference.
    at mx.controls::DataGrid/makeRowsAndColumns()[C:\autobuild\3.5.0\frameworks\projects\framework\src\mx\controls\DataGrid.as:1563]
    at mx.controls.listClasses::ListBase/makeRowsAndColumnsWithExtraRows()[C:\autobuild\3.5.0\frameworks\projects\framework\src\mx\controls\listClasses\ListBase.as:1377]
    at mx.controls.listClasses::ListBase/updateDisplayList()[C:\autobuild\3.5.0\frameworks\projects\framework\src\mx\controls\listClasses\ListBase.as:3722]
    at mx.controls.dataGridClasses::DataGridBase/updateDisplayList()[C:\autobuild\3.5.0\frameworks\projects\framework\src\mx\controls\dataGridClasses\DataGridBase.as:581]
    at mx.controls::DataGrid/updateDisplayList()[C:\autobuild\3.5.0\frameworks\projects\framework\src\mx\controls\DataGrid.as:1449]
    at mx.controls.listClasses::ListBase/validateDisplayList()[C:\autobuild\3.5.0\frameworks\projects\framework\src\mx\controls\listClasses\ListBase.as:3344]
    at mx.managers::LayoutManager/validateDisplayList()[C:\autobuild\3.5.0\frameworks\projects\framework\src\mx\managers\LayoutManager.as:622]
    at mx.managers::LayoutManager/doPhasedInstantiation()[C:\autobuild\3.5.0\frameworks\projects\framework\src\mx\managers\LayoutManager.as:695]
    at Function/http://adobe.com/AS3/2006/builtin::apply()
    at mx.core::UIComponent/callLaterDispatcher2()[C:\autobuild\3.5.0\frameworks\projects\framework\src\mx\core\UIComponent.as:8744]
    at mx.core::UIComponent/callLaterDispatcher()[C:\autobuild\3.5.0\frameworks\projects\framework\src\mx\core\UIComponent.as:8684]
    at flash.utils::Timer/_timerDispatch()
    at flash.utils::Timer/tick()

  6. Hi, I’m having a strange bug when I set my locked columns dynamically. I’m using a numeric stepper to set the number. After the user changes the number the locked columns adjust on the grid as they should. However, when the user scrolls horizontally, the header row labels don’t lock, they seemingly disappear. Any idea why?

Comments are closed.