2 Replies Latest reply on Jul 13, 2006 9:46 PM by jpwrunyan

    How do I access listData for a DataGrid itemRenderer?

    jpwrunyan Level 1
      I want to make simple reusable components in .mxml to use in my dataGrid classes. I do NOT want to specify the data field because I might use the same renderer in multiple columns of the same Grid (for example a check box renderer) and I do not want to make several identical components whose only difference is the value they draw from "data". To do this, I need access to "listData". Specifically listData.dataField. According to the docs I need to implement mx.controls.listClasses.IDropInListRenderer. I have tried the following in my mxml code:

      <mx:Component id="reusableEditor">
      <mx:HBox implements="mx.controls.dataGridClasses.DataGridItemRenderer">
      import mx.controls.dataGridClasses
      .. contents and logic for displaying data[listData.dataField]..
      </mx:HBox>
      </mx:Component>

      I get an unhelpful error in Flex Builder saying that "An internal build error has occurred" and only now guess that it comes from the line "implements="mx.controls.dataGridClasses.DataGridItemRenderer"" (when I remove that line, things work fine). I have not found anywhere to check if I am implementing this correctly because there is no example to work from that does what I want to do--even though I use DataGrid 100s of times more often than any other list class! The TreeRenderer example later in the docs is the only code addressing this issue but it involves an AS Class that does not extend (as far as I can tell) a Container like HBox and implements no interface.

      To put the question simply, how can I get access to listData???
        • 1. Re: How do I access listData for a DataGrid itemRenderer?
          jpwrunyan Level 1
          Figured one thing out... DataGridItemRenderer is obviously not an interface so you don't implement it...
          so I guess <DataGridItemRenderer> should be the tag preceeding <HBox>???
          • 2. Re: How do I access listData for a DataGrid itemRenderer?
            jpwrunyan Level 1
            the <mx:DataGridItemRenderer> tag was not the solution either...
            I finally figured out what the ambiguous compiler error meant... I hadn't implemented the functions required for the interface. Below is working code that either declared as an internal component or an external .mxml file will display the value of its column without explicitely defining what that value is.

            Although this component is extremely simple, it was very difficult to figure out how to implement from the docs... I hope someone from Adobe takes note.

            <?xml version="1.0" encoding="utf-8"?>
            <mx:Application xmlns:mx=" http://www.adobe.com/2006/mxml" layout="absolute">
            <mx:Script>
            <![CDATA[
            [Bindable]
            public var dp:Array = [{num:2, bool:true}, {num:3, bool:false}];
            ]]>
            </mx:Script>


            <!-- BrainlesslySimpleCheckBoxRenderer class -->
            <mx:Component id="cbren3">
            <mx:HBox horizontalAlign="center" verticalAlign="middle" implements="mx.managers.IFocusManagerComponent, mx.controls.listClasses.IDropInListItemRenderer">
            <mx:Script>
            <![CDATA[
            import mx.controls.listClasses.BaseListData;
            import mx.controls.dataGridClasses.DataGridListData;

            private var _listData:DataGridListData;

            [Bindable("dataChange")]
            public function get listData():BaseListData {
            return _listData;
            }

            public function set listData(value:BaseListData):void {
            _listData = DataGridListData(value);
            }

            override public function drawFocus(focused:Boolean):void {
            check.setFocus();
            }

            override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void {
            super.updateDisplayList(unscaledWidth, unscaledHeight);
            if (super.data) {
            var dgListData:DataGridListData = DataGridListData(listData);
            //for some reason, setting check.selected here results in buggy behavior
            //check.selected = data[dgListData.dataField];
            }
            }

            //defining a getter based on the "dataChange" event seems to update the CheckBox value properly when
            //clicked, rolledOut, sorted, etc...
            //also, doing it this way circumvents those annoying "Data binding will not be able to detect changes... blah blah"
            [Bindable("dataChange")]
            public function get val():Boolean {
            return Boolean(data[_listData.dataField]);
            }

            ]]>
            </mx:Script>
            <mx:Boolean id="blorch" />
            <mx:CheckBox id="check" selected="{val}" change="blorch=check.selected" updateComplete="blorch=check.selected" />
            </mx:HBox>
            </mx:Component>

            <mx:DataGrid id="test" editable="true" dataProvider="{dp}">
            <mx:columns>

            <mx:DataGridColumn dataField="num" headerText="num" />

            <mx:DataGridColumn dataField="bool" headerText="Sent" itemRenderer="{cbren3}" rendererIsEditor="true" editorDataField="blorch">

            </mx:DataGridColumn>
            <mx:DataGridColumn dataField="num" headerText="num" editable="true" />
            </mx:columns>
            </mx:DataGrid>
            </mx:Application>

            if anyone has suggestions or feedback, please let me know... I am still trying to figure out the best way to do this.