1 Reply Latest reply on Dec 5, 2006 11:09 AM by ntsiii

    Custom itemRenderer - Bug?

    jkerr8
      Hi, I have an example of some code that I can't figure out. What I'm doing may not be the best way to do what I want, but I believe is should work, and can't figure out why it doesn't. I have a datagrid with two columns, and the second column uses a custom itemRenderer to draw multiple circles depending on nested XML data for that row. In the set data function of my itemRenderer, I'm trying to get the width of the column, and use that to calculate where to put my circle, as a value of 1 to 10.

      - The first time, the set data is called four times where there are three rows
      - The first time it's called, this.width is zero
      - When resizing column widths, set data is called again - the first time only for the 2nd and 3rd rows, but with the correct width
      - Subsequent times it's called for all three rows, but the first row uses the LAST width, not the new width

      Any ideas? Here's my code:

      Project name is FlexSample, first file is FlexSample.mxml, then other two files are MyComponents/MyItemRenderer.as and MyComponents/PointComponent.as

      FlexSample.mxml

      <?xml version="1.0" encoding="utf-8"?>
      <mx:Application xmlns:mx=" http://www.adobe.com/2006/mxml" xmlns="*"
      width="100%" height="100%"
      initialize="init()" horizontalGap="0" verticalGap="0" >

      <mx:Script>
      <![CDATA[
      import mx.events.ResizeEvent;

      import mx.controls.Alert;
      import mx.rpc.events.ResultEvent;
      import mx.rpc.events.FaultEvent;
      import mx.rpc.http.HTTPService;
      import mx.events.*;

      [Bindable]
      public var myXML:XML=
      <ROWSET>
      <ROW>
      <POINTS>
      <POINT>
      <POINT_ID>90686</POINT_ID>
      <X_VALUE>2</X_VALUE>
      </POINT>
      <POINT>
      <POINT_ID>90806</POINT_ID>
      <X_VALUE>8</X_VALUE>
      </POINT>
      </POINTS>
      <NOTE_TX>Points are 2 and 8</NOTE_TX>
      </ROW>
      <ROW>
      <POINTS>
      <POINT>
      <POINT_ID>90111</POINT_ID>
      <X_VALUE>4</X_VALUE>
      </POINT>
      <POINT>
      <POINT_ID>90222</POINT_ID>
      <X_VALUE>6</X_VALUE>
      </POINT>
      </POINTS>
      <NOTE_TX>Points are 4 and 6</NOTE_TX>
      </ROW>
      <ROW>
      <POINTS>
      <POINT>
      <POINT_ID>90333</POINT_ID>
      <X_VALUE>1</X_VALUE>
      </POINT>
      <POINT>
      <POINT_ID>90444</POINT_ID>
      <X_VALUE>10</X_VALUE>
      </POINT>
      </POINTS>
      <NOTE_TX>Points are 1 and 10</NOTE_TX>
      </ROW>
      </ROWSET>;

      ]]>
      </mx:Script>

      <mx:DataGrid width="100%" height="100%" id="dgMain" dataProvider="{myXML.ROW}"
      fontFamily="Verdana" fontSize="10" color="#000066">
      <mx:columns>
      <mx:DataGridColumn headerText="Note" dataField="NOTE_TX"/>
      <mx:DataGridColumn headerText="Points" dataField="POINT" id="dgcPoints"
      itemRenderer="MyComponents.MyItemRenderer"/>
      </mx:columns>
      </mx:DataGrid>
      </mx:Application>


      MyItemRenderer.as

      // ActionScript file
      package MyComponents {

      import mx.controls.*;
      import mx.core.*;
      import mx.controls.dataGridClasses.DataGridListData;
      import mx.controls.listClasses.*;
      import flash.display.*;
      import mx.core.*;
      import mx.controls.*;
      import flash.events.*;
      import mx.managers.PopUpManager;
      import mx.events.*;

      public class MyItemRenderer extends mx.core.Container implements IListItemRenderer{

      public function MyItemRenderer() {
      super();
      }

      override public function set data(oValue:Object):void {

      this.removeAllChildren();

      //oValue contains whole ROW in XML format...
      var n:int = 0;

      if(this.width==0){
      trace("set data:width 0!");
      }

      if (oValue != null && this.width>0) {

      var m:int = this.getChildren().length;

      var nWidth:int = this.width;

      var xXML:XML = new XML(oValue);
      for(var s:String in xXML.POINTS.children()){
      var nXValue:int = xXML.POINTS.children()[s].X_VALUE;

      //Total width is from 0-9, padding of 5 on left and right to account for circle width
      var n:int = (((nXValue -1)/10) * (this.width-10)) + 5;

      trace("set data: Width:" + this.width + " XValue:" + nXValue + " X:" + n);

      var u:PointComponent = new PointComponent(0x0000EE, n);
      this.addChild(u);
      }
      }

      }

      }
      }


      PointComponent.as

      package MyComponents
      {
      import mx.core.UIComponent;
      import mx.controls.Alert;

      public class PointComponent extends UIComponent
      {
      public function PointComponent(pnColor:uint, pnX:int){
      super();
      graphics.clear();
      graphics.beginFill(pnColor);
      graphics.drawCircle(pnX, 10, 7);
      }
      }
      }
        • 1. Re: Custom itemRenderer - Bug?
          ntsiii Level 3
          A complete runnable example, that's great, I will give it a try.

          In the meantime, for "...set data is called four times where there are three rows...", I have noticed this as well but have no explanation. The first time, the "value" object is "null", so I always wrap the code in if (value != null) {}

          I'll post when I get a chance to look at your sample.

          Tracy