package datagrid { import flash.events.Event; import mx.collections.IList; import mx.events.CollectionEvent; import mx.events.CollectionEventKind; import mx.events.FlexEvent; import spark.components.DataGrid; import spark.events.GridSelectionEvent; import spark.events.GridSelectionEventKind; /** * Fixes binding issues with spark DataGrid component. * These issues are the following: * You can use the DataGrid's selectedItem, selectedItems, etc properties for data binding. * However in certain scenarios the getter methods will not get updated for binding. * * These scenarios include: * - when the user removes the currently selected dataProvider element * - when there's a currently selected item, and a new dataProvider is assigned to the DataGrid * * In these cases the selectedItem, selectedIndex (and other corresponding properties) * will be set to their correct value, their bindable getter methods though will not * get called for update. * * To fix these issues BindableDataGrid class dispatches the FlexEvent.VALUE_COMMIT Event * in the above specified scenarios to update the bindable properties. * * @author Andrew Varga - www.andrewvarga.com * */ public class BindableDataGrid extends DataGrid { public function BindableDataGrid() { super(); } override public function set dataProvider(value:IList):void { // removes EventListener from the previous (old) dataProvider var tDataProvider:IList = dataProvider; if (tDataProvider) { tDataProvider.removeEventListener(CollectionEvent.COLLECTION_CHANGE, dataProvider_collectionChangeHandler, false); } // this part fixes binding when you assign a new dataProvider // selectedItem is set to null prior to the dataProvider set, // so the Grid will catch it as the selection changes // (since at that point selectedItem is not yet null) // and so it will dispatch the VALUE_COMMIT Event selectedItem = null; super.dataProvider = value; // if a row is removed, the VALUE_COMMIT Event will be dispatched value.addEventListener(CollectionEvent.COLLECTION_CHANGE, dataProvider_collectionChangeHandler, false, 0, true); } private function dataProvider_collectionChangeHandler(e:CollectionEvent):void { if (e.kind == CollectionEventKind.REMOVE || e.kind == CollectionEventKind.REFRESH) { dispatchEvent( new FlexEvent(FlexEvent.VALUE_COMMIT) ); } } } }