How to re-render itemRenderer for a DropDownList in Flex4?

7k Views Asked by At

I have created a custom ComboCheck which extends the spark DropDownList that is a DropDownList of checkboxes. Inside of my itemRenderer I have the code:

[Bindable]override public function set data (value:Object):void {
    if (value!=null) {
        _data = value;
        item.label = value.label;
        item.group = value.group;
        item.toolTip = value.toolTip;
        item.selected = value.selected;
        item.enabled = value.enabled;
    ...

This code allows me to enable and disable individual items in the dropdown list so that when it is rendered, you will not be able to select the items I have disabled. I am trying to create the functionality where a user clicks on a specific item that is in a given category which results in all other categories being disabled until you de-select everything.

My issue is that while the DropDownList is up, the items have already been rendered so changing the enabled property on each item that should be disabled doesn't change the items that have already been rendered. If you scroll down and back up to re-render the data it works fine.

Is there a way to have the itemRenderer re-render the data on the screen so that it refreshes and applies this update?

Below is sample code of an item being selected, it disables every other item then enables only the one you have selected. I also have a itemDeselect function that decrements the itemCount and enables everything

private function itemSelect(evt:Event):void{
            itemCount++;
            var myText:String = '';
            var items:Vector.<Object> = allItems.selectedItems;
            if(itemCount == 1){
                    for each(var obj:Object in allItems.dataProvider){
                        obj.enabled = false;
                    }
            }
            for (var i:String in items) {
                if(items[i].group == "HU"){
                    items[i].enabled = true;
                    huList[items[i].label] = items[i].selected;
                }else if(items[i].group == "ALL"){
                    items[i].enabled = true;
                    allCase = items[i].selected;
                }else{
                    items[i].enabled = true;
                    otherList[items[i].label] = items[i].selected;
                }

            }

            selectionChanged = true;
}

This works but again it is not re-rendered so the obj.enabled=false does not appear unless you scroll down and back up.

EDIT: Final Solution
Using the third option suggested by www.Flextras.com I used the itemUpdated property dataProvider.itemUpdated(obj) so inside of the

for each(var obj:Object in allItems.dataProvider){
    obj.enabled = false;
    allItems.dataProvider.itemUpdated(obj);
}

This will also not cause the dropdownlist to reset to scrollPosition 0

3

There are 3 best solutions below

6
On BEST ANSWER

Is there a way to have the itemRenderer re-render the data that is shown to apply this update?

I have three ways.

1) invalidate the list's dataGroup instead of the list.

listInput.dataGroup.invalidateDisplayList();

2) Refresh the dataProvider

(listInput.dataProvider as ArrayCollection).refresh();

3) When the dataProvider item changes, invoke the itemUpdated() property on the collection. No code sample for this one, sorry.

The one thing I often forget to do in this situation is implement the renderer so that it knows to switch itself back into the 'non-active' state. So in your set data method of the itemRenderer be sure to add an else condition putting all those values back to some default.

0
On

You can also add event listener for dataChange event to the item renderer itself. This event gets fired after data property is changed.

<s:ItemRenderer dataChange="updateView(event)">
    <fx:Script>
        <![CDATA[
            protected function updateView(event:Event):void{
                //update logic
            }
        ]]>
    </fx:Script>
</s:ItemRenderer>
0
On

I found the way to "re-render", just override the set data function and update all the properties in the itemRenderer: eg

I have a DataGrid with a column with an itemRenderer that shows a different backgroundColor for each item in my dataProvider.

<mx:DataGrid>
  <mx:columns>
    <mx:DataGridColumn itemRenderer="myItemRenderer"/>
  </mx:columns>
</mx:DataGrid>

//myItemRenderer:

override public function set data( value:Object ) : void {
  super.data = value;
  if( value > 0) setStyle("backgroundColor",0xff99ff);
  else setStyle("backgroundColor",0xffffff);
}

That's all.