Adobe Flex 3 Help

Setting the itemRenderer or itemEditor property in ActionScript

The itemRenderer and itemEditor properties are of type IFactory. When you set these properties in MXML, the MXML compiler automatically casts the property value to the type ClassFactory, a class that implements the IFactory interface.

When you set these properties in ActionScript, you must explicitly cast the property value to ClassFactory, as the following example shows:

<?xml version="1.0"?>
<!-- itemRenderers\list\AppListStateRendererEditorAS.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">

    <mx:Script>
        <![CDATA[
            import mx.core.ClassFactory; 
            
            // Cast the value of the itemRenderer property
            // to ClassFactory.
            public function initCellEditor():void {  
                myList.itemRenderer=new ClassFactory(RendererState);
            }           
        ]]>
    </mx:Script>

    <mx:List id="myList" variableRowHeight="true" 
            height="180" width="250" 
            backgroundColor="white" 
            initialize="initCellEditor();"> 
        <mx:dataProvider>
            <mx:Object label="Alaska" 
                data="Juneau" 
                webPage="http://www.state.ak.us/"/>
            <mx:Object label="Alabama" 
                data="Montgomery" 
                webPage="http://www.alabama.gov/" />
            <mx:Object label="Arkansas" 
                data="Little Rock" 
                webPage="http://www.state.ar.us/"/>                  
        </mx:dataProvider>
    </mx:List>
</mx:Application>

The executing SWF file for the previous example is shown below:

Shown below is the code for the RenderState.mxml item renderer:

<?xml version="1.0"?>
<!-- itemRenderers\list\RendererState.mxml -->
    <mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml" >    
        <mx:Script>
            <![CDATA[
                // Import Event and URLRequest classes.
                import flash.events.Event;
                import flash.net.URLRequest;
                
                private var u:URLRequest;
            
                // Event handler to open URL using navigateToURL().
                private function handleClick(eventObj:Event):void {
                    u = new URLRequest(data.webPage);
                    navigateToURL(u);
                }   
            ]]>
        </mx:Script>
    
        <mx:HBox >  
            <!-- Use Label controls to display state and capital names. -->
            <mx:Label id="State" text="State: {data.label}"/>
            <mx:Label id="Statecapital" text="Capital: {data.data}" />
        </mx:HBox>

        <!-- Define the Link control to open a URL. -->
        <mx:LinkButton id="webPage" label="Official {data.label} web page" 
            click="handleClick(event);" color="blue"  />
    </mx:VBox>

About the item renderer and item editor life cycle

Flex creates instances of item renderers and item editors as needed by your application for display and measurement purposes. Therefore, the number of instances of an item renderer or item editor in your application is not necessarily directly related to the number of visible item renderers. Also, if the list control is scrolled or resized, a single item renderer instance may be reused to represent more than one data item. Thus, you should not make assumptions about how many instances of your item renderer and item editor are active at any time.

Because Flex can reuse an item renderer, ensure that you fully define its state. For example, you use a CheckBox control in an item renderer to display a true (checked) or false (unchecked) value based on the current value of the data property. A common mistake is to assume that the CheckBox control in the item renderer is always in its default state of unchecked. Developers then write an item renderer to inspect the data property for a value of true and set the CheckBox control to checked if found.

However, you must take into account that the CheckBox may already be checked. So, you must inspect the data property for a value of false, and explicitly uncheck the control if it is checked.

Accessing the listData property

If a component implements the IDropInListItemRenderer interface, you can use its listData property to obtain information about the data passed to the component when you use the component in an item renderer or item editor. The listData property is of type BaseListData, where the BaseListData class defines the following properties:

Property

Description

owner

A reference to the list control that uses the item renderer or item editor.

rowIndex

The index of the row of the DataGrid, List, or Tree control relative to the currently visible rows of the control, where the first row is at an index of 1.

label

The text representation of the item data based on the List class's itemToLabel() method.

The BaseListData class has three subclasses: DataGridListData, ListData, TreeListData that define additional properties. For example, the DataGridListData class adds the columnIndex and dataField properties that you can access from an item renderer or item editor.

The data type of the value of the listData property depends on the control that uses the item renderer or item editor. For a DataGrid control, the value is of type DataGridListData; for a List control, the value is of type ListData; and for a Tree control, the value is of type TreeListData.

The TextArea control is one of the Flex controls that implements the IDropInListItemRenderer interface The item renderer in the following example uses the listData property of the TextArea control to display the row and column of each item renderer in the DataGrid control:

<?xml version="1.0"?>
<!-- itemRenderers\dataGrid\myComponents\RendererDGListData.mxml -->
<mx:TextArea xmlns:mx="http://www.adobe.com/2006/mxml" 
    preinitialize="initTA();">

    <mx:Script>
        <![CDATA[
        
            import mx.controls.dataGridClasses.DataGridListData;
            import flash.events.Event;
        
            public function initTA():void {         
                addEventListener("dataChange", handleDataChanged);
            }   

            public function handleDataChanged(event:Event):void {       
                // Cast listData to DataGridListData. 
                var myListData:DataGridListData = 
                    DataGridListData(listData);
                
                // Access information about the data passed 
                // to the cell renderer.
                text="row index: " + String(myListData.rowIndex) + 
                    " column index: " + String(myListData.columnIndex);
            }   
        ]]>
    </mx:Script>
</mx:TextArea>

Because you use this item renderer in a DataGrid control, the data type of the value of the listData property is DataGridListData. You use the dataChange event in this example to set the contents of the TextArea control every time the data property changes.

The DataGrid control in the following example uses this item renderer:

<?xml version="1.0"?>
<!-- itemRenderers\dataGrid\MainDGListDataRenderer.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
    
    <mx:Script>
        <![CDATA[
            import mx.collections.ArrayCollection;
        
            [Bindable]
            public var initDG:ArrayCollection = new ArrayCollection([
                { Company: 'Acme', Contact: 'Bob Jones', 
                    Phone: '413-555-1212', Date: '5/5/05'},
                { Company: 'Allied', Contact: 'Jane Smith', 
                    Phone: '617-555-3434', Date: '5/6/05'} 
            ]);
        ]]>
    </mx:Script>

    <mx:Panel paddingTop="10" paddingBottom="10" 
        paddingLeft="10" paddingRight="10" >

        <mx:DataGrid id="myGrid" dataProvider="{initDG}" 
                variableRowHeight="true"> 
            <mx:columns>
                <mx:DataGridColumn dataField="Company" 
                    itemRenderer="myComponents.RendererDGListData"/>
                <mx:DataGridColumn dataField="Contact" 
                    itemRenderer="myComponents.RendererDGListData"/>
                <mx:DataGridColumn dataField="Phone" 
                    itemRenderer="myComponents.RendererDGListData"/>
                <mx:DataGridColumn dataField="Date" 
                    itemRenderer="myComponents.RendererDGListData"/>
            </mx:columns>       
        </mx:DataGrid>      
    </mx:Panel>     
</mx:Application>

The executing SWF file for the previous example is shown below:

This code produces the following image of the DataGrid control:

Each cell of the DataGrid control displays its column and row index

As you can see in this image, each cell of the DataGrid control displays its column and row index.

Handling data binding warnings from the compiler

Many of the following examples, and those in Working with Item Editors, define the application data as an ArrayCollection of Objects. However, you might get compiler warning for these examples because the Object class does not support data binding. That does not matter with these examples because the data is static.

If your data is dynamic, and you want it to support data binding, you can instead define your own data class that supports binding. For example, you could create the following subclass of Object that supports data binding, and use it instead:

package
{
    [Bindable]
    public class MyBindableObj extends Object
    {
        public function MyBindableObj()  {
            super();
        }
  
        public var Artist:String = new String();
  
        public var Album:String = new String();
 
        public var Price:Number = new Number();

        public var Cover:String = new String();                          
    }
}

By inserting the [Bindable] metadata tag before the class definition, you specify that all public properties support data binding. For more information on data binding, see Binding Data and Metadata Tags in Custom Components.