Question

I'm using a DataGrid in one of my project, with a custom ItemRenderer for one of the column to represent a boolean value as a CheckBox

<s:DataGrid id="clients" resizableColumns="false">
    <s:columns>
        <s:ArrayList>
            <s:GridColumn dataField="fullName" headerText="Client name" />
            <s:GridColumn dataField="active" headerText="Active?" width="90"
                          itemRenderer="CheckBoxGridItemRenderer"/>
        </s:ArrayList>
    </s:columns>
</s:DataGrid>

And here is the code of CheckBoxGridItemRenderer:

<?xml version="1.0" encoding="utf-8"?>
<s:GridItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009" 
                    xmlns:s="library://ns.adobe.com/flex/spark" 
                    xmlns:mx="library://ns.adobe.com/flex/mx"
                    clipAndEnableScrolling="true">

    <fx:Script>
        <![CDATA[
            override public function prepare(hasBeenRecycled:Boolean):void {
                checkBox.selected = Boolean(data[column.dataField]);
            }
        ]]>
    </fx:Script>

    <s:CheckBox id="checkBox" horizontalCenter="0" />

</s:GridItemRenderer>

Now here is my question: What is the best way to handle the change in data from the class I declared the DataGrid ?

I tried to change the data value from within my custom item renderer class:

private function valueChange():void
{
    data.active = checkBox.selected;
}

[...]

<s:CheckBox id="checkBox" change="valueChange()" />

and then listen to CollectionEvent.COLLECTION_CHANGE event on the dataProvider of the DataGrid but I never handle any change. Any thoughts or advices?

Was it helpful?

Solution 2

As I found a solution to my problem, I will post it here, but I leave the question open for some time in case someone come up with a better one.

First I created a CustomEvent (I could use the CollectionEvent class but this way I'm sure I don't mess up with the internal logic of the DataGrid)

package
{
    import flash.events.Event;

    public class CustomEvent extends Event
    {
        public static const CHANGE:String = "change";

        public var column:String;
        public var data:Object;

        public function CustomEvent(column:String, data:Object)
        {
            super(CHANGE, true);
            this.column = column;
            this.data = data;
        }
    }
}

Notice the call to super() with bubbles set to true. This is actually needed for the event to be handle here.

Then I modified my CheckBoxGridItemRenderer to dispatch this event when the checkbox is selected/deselected:

<?xml version="1.0" encoding="utf-8"?>
<s:GridItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009" 
                    xmlns:s="library://ns.adobe.com/flex/spark" 
                    xmlns:mx="library://ns.adobe.com/flex/mx" clipAndEnableScrolling="true">

    <fx:Script>
        <![CDATA[
            import CustomEvent;

            override public function prepare(hasBeenRecycled:Boolean):void {
                if (data)
                {
                    checkBox.selected = Boolean(data[column.dataField]);
                }
            }

            private function valueChange():void
            {
                data[column.dataField] = checkBox.selected;
                dispatchEvent(new CustomEvent(column.dataField, data));
            }
        ]]>
    </fx:Script>

    <s:CheckBox id="checkBox" horizontalCenter="0" change="valueChange()" />
</s:GridItemRenderer>

Finally I only have to listen to my custom event dispatched by the DataGrid instance:

clients.addEventListener(CustomEvent.CHANGE, handleCustomEvent);

OTHER TIPS

Where do you change the data. When an element of data collection changed, the DataGrid can detect nothing unless you dispatch CollectionEvent.COLLECTION_CHANGE for the data collection. In addition, the data collection should be something like ArrayCollection, not Array.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top