Apache – Flex: Combobox loses is focus when data-provider updated

apache-flex

It seems that ComboBoxes loose their selected item after their dataProvider updates, even if the same selected item is still in the dataProvider. They convert back to the first item being selected. Is there anyway to prevent this? So that if the same object is in the dataProvider it keeps the same object selected and only reverts back to the first index if the selected object is not in the updated dataProvider?

Thanks!

Best Answer

If the ComboBox looses its selected item, it means the dataProvider isn't updated - it is replaced. If you bind a ComboBox to an ArrayCollection and then add an item to the AC, The ComboBox is updated without loosing its selectedItem.

Sometimes you have to replace the dataProvider and in those cases, you have to listen for the updateComplete-event and reset the selectedItem. You can try this code:

<mx:Script>
    <![CDATA[
        import mx.controls.ComboBox;
        import mx.events.ListEvent;
        import mx.events.FlexEvent;
        import mx.collections.ArrayCollection;

        [Bindable]
        private var dp:ArrayCollection = new ArrayCollection(["Item 1", "Item 2", "Item 3"]);

        private var selectedItem:*;
        private var dataProvider:*;

        private function onChange(event:ListEvent):void {
            selectedItem = (event.currentTarget as ComboBox).selectedItem;
        }
        private function onUpdateComplete(event:FlexEvent):void {
            trace(event);
            var cb:ComboBox = event.currentTarget as ComboBox;
            if(dataProvider == null || cb.dataProvider != dataProvider) {
                if(selectedItem != null && cb.selectedItem != selectedItem) cb.selectedItem = selectedItem;
                if(cb.selectedIndex < 0) cb.selectedIndex = 0;
                dataProvider = cb.dataProvider;
            }
        }

        private function extendDP():void {
            dp.addItem("Item " + (dp.length +1));
            var ac:ArrayCollection = new ArrayCollection(dp.source);
            dp = ac;
        }

        private function reduceDP():void {
            dp.removeItemAt(dp.length -1);
            var ac:ArrayCollection = new ArrayCollection(dp.source);
            dp = ac;
        }
    ]]>
</mx:Script>

<mx:VBox>
    <mx:ComboBox dataProvider="{dp}" change="onChange(event)" updateComplete="onUpdateComplete(event)" />
    <mx:Button label="Extend dp" click="extendDP()" />
    <mx:Button label="Reduce dp" click="reduceDP()" />
</mx:VBox>

It creates a ComboBox and binds it to an ArrayCollection. The two buttons adds and removes items from the collection.

Related Topic