ComboBox madness continues

The saga with data binding problems in ComboBox component continues. The selectedIndex/selectedItem concept seems to be just undeveloped.

My previous fix has not covered all possible scenarios of the property assignment order. If you set dataProvider property it kicks out selectedItem/selectedIndex values. Here is attempt to make Combobox more conscious about its data.

package
{
    import mx.controls.ComboBox;
    public class SmartComboBox extends ComboBox
    {
        public function CSmartComboBox()
        {
            super();
        }

        /**
        *  bind to this property instead of selectedItem
        */
        private var _selectedItemEx:Object;

        public function set selectedItemEx(value:Object):void
        {
            _selectedItemEx = value;
        }

        public function get selectedItemEx():Object
        {
            return _selectedItemEx;
        }

        /**
         * This method fixes the nasty bug in ComboBox
         * If value is null, it tries to find in dataProvider, can't find it, so it leaves controls as is it is,
         * instead of resetting it.
         */
        override public function set selectedItem(value:Object):void
        {
            if (value == null)
            {
                //first check if our real selectedItem is set
                if (_selectedItemEx)
                {
                    //assign real value
                    // NB if _selectedItemEx contains invalid data, setter from the parent class
                    //will ignore the value and set the property to null.
                    super.selectedItem = _selectedItemEx;
                }
                else
                {
                    //reset the control
                    super.selectedIndex = -1;
                }
            }
            else
            {
                super.selectedItem = value;
            }
        }
 

        /**
        * After dataProvider assignment, restore real selectedItem
        */
        override public function set dataProvider(value:Object):void
        {
            super.dataProvider = value;
            //after assignment, restore real selectedItem
            //NB this is still safe, as setter check the value against the dataProvider
            super.selectedItem = _selectedItemEx;
        }


        /**
        *  reset control (-1) only if real selectedItem is null
        */
        override public function set selectedIndex(value:int):void
        {
            if (value == -1)
            {
                //reset only if we don't have a saved value!
                if (!_selectedItemEx)
                {
                     super.selectedIndex = value;
                }
            }
            else
            {
                super.selectedIndex = value;
            }
        }
    }
}

One Response to “ComboBox madness continues”

  1. Zmogas says:

    I was stuck on setting selectedIndex for ComboBox for half a day. Googling did not helped much. I was already thinking about using your package for SmartCombo, but your post showed for me what problem do I have. I used function to find item index and debug shows, that function works ok and returns right index. But before find function is called few times while dataProvider is not setuped yet. So, I got situation that some combos are selected ok, but some not (first 3 on page are ok, the rest not, copying code and just changing id – got first selected, another stay on first item)

    I solved my problem by using bindable variable for selectedIndex property and two bindSetters – one looks for data change, another for dataProvider change.

    Some snippets form my code:

    BindingUtils.bindSetter(setIndex, this, “dataOptions”);
    BindingUtils.bindSetter(setIndex, this, [“ddata”, “itemOne”]);

    [Bindable]
    public var myIndex:int = -1;

    public function setIndex(o:Object):void
    {
    myIndex = U.findIndex(dataOptions, ddata.itemOne);
    }

Leave a Reply