Invalidation resetting ComboBox

Posted on 2009-12-19
Last Modified: 2012-06-27

When using the following custom itemRenderer class, I'm updating another cell in the same row as a ComboBox to reflect a value determined by that ComboBox's selectedItem.  I use the invalidateList method to update the containing DataGrid's display.

This works.

However, the ComboBox selection returns to the default when this happens, although the updated property in the other cell remains (which is correct).

How do I get the ComboBox to retain the selected option?

I've tried using variations of validateNow, invalidateDisplayList, etc and calling from both the itemRenderer itself and the containing DataGrid.  Calling invalidateList from the DataGrid is the only method that properly updates the related cell value; but this also causes the ComboBox to "reset".  I've also tried with and without the prompt property set - this has no effect on the behavior I'm describing.  I've also tried listening to the DataChange event and performing the changeHandler operations there - this has no effect, and in fact I can't even get an Alert to fire on the DataChange except when first instantiating the component.

package renderers {
	import mx.controls.DataGrid;
	import mx.controls.ComboBox;
	import mx.controls.dataGridClasses.*;
	public class UOMBox extends ComboBox {		
		private function changeHandler(event:Event):void{
			data.unitRate = selectedItem.RATE;
		override public function set data(value:Object):void{ = value;
		 	dataProvider = value.uom;
		public function UOMBox():void{
			prompt = "UOM";
			labelField = "LABEL";
			addEventListener("change", changeHandler, false, 0, true);

Open in new window

Question by:moagrius
    LVL 10

    Expert Comment

    Oh man, yes I remember the first time I hit this problem, probably one of the trickiest flex 'features' to deal with that I've encountered.
    Can't answer it right now, I'll knock up an example over the next 24 hours if you can wait :)
    LVL 19

    Author Comment

    no problem - thanks man
    LVL 19

    Author Comment

    I found a simple workaround - I just saved the current selectedIndex to a variable, allow the refresh to happen, and set it back to that saved value.

                  override public function set data(value:Object):void{
                       var _selectedIndex:int = selectedIndex;
              = value;
                       dataProvider = value.uom;
                       selectedIndex = _selectedIndex;

    still, i'd be interested to see your approach and would be happy to give you the points
    LVL 10

    Accepted Solution

    Sorry for delay, got tied up with the holidays ;)

    After re-reading your question, I realised this is a slightly different problem to what I had first understood.
    That said I see your solution is following a line that works for you, however I think this will only work as long as you don't scroll the grid around.

    A situation to watch out for is that 'set data' is called not only when the data for the same row is set again following your call to 'invalidateList', but might also be called when you scroll the grid and the itemrenderer gets reused for a different data row.
    If that happens, you might be trying to apply the previously selected index to an index which doesn't exist for the new value.uom which becomes the dataprovider for your renderer. Also in the row your data item gets scrolled to, you might lose the selected index, as you'll try to apply a selectedindex from a previous row to the new row. In summary, when you're creating an itemrenderer, you cannot make an assumption that the row it is displaying has not changed on each call to 'set data'.

    The only way I find to avoid any problems with state of itemrenderers, is to physically store the state in the underlying data items. So if you need to store selectedIndex state, you'll need to create a property on your data to hold that state. Your itemrenderer needs to also be an itemeditor, so if you change the selectedItem index the index gets written to the data record, and your 'set data' function should always read from the data item to retrieve state.

    Any other way will introduce strange happenings which can be hard to debug. If you need to preserve the combo selection for any given row regardless of scrolling etc., treat the selectedindex state as a first-class citizen of the data you're working with.
    LVL 19

    Author Comment

    you're right - in fact, overriding the data setter in this turned out to be the source of many issues.  i ended up casting the custom item renderers as instances of ClassFactory, and using the properties property to set the custom ComboBox's dataProvider.

    thanks for the input

    Featured Post

    Maximize Your Threat Intelligence Reporting

    Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

    Join & Write a Comment

    First things first - Preparation We need all the part for this install and it's much nicer to have them all on hand when you need them so here's what's required. Download Eclipse 3.5 32 bit (I like the Classic flavour) from here. (http://www.e…
    It can often be challenging to stay relevant in the rapidly evolving world of technology. This can make recruiting talent difficult for companies of all sizes.
    This video gives you a great overview about bandwidth monitoring with SNMP and WMI with our network monitoring solution PRTG Network Monitor ( If you're looking for how to monitor bandwidth using netflow or packet s…
    In this tutorial you'll learn about bandwidth monitoring with flows and packet sniffing with our network monitoring solution PRTG Network Monitor ( If you're interested in additional methods for monitoring bandwidt…

    754 members asked questions and received personalized solutions in the past 7 days.

    Join the community of 500,000 technology professionals and ask your questions.

    Join & Ask a Question

    Need Help in Real-Time?

    Connect with top rated Experts

    20 Experts available now in Live!

    Get 1:1 Help Now