actionscript 3 - Flex DataGrid row color spreads when scrolled up down -


i'm facing issue datagrid row background color being spread when datagrid vertically scrolled.

i'm assuming happening because itemrenderers recycled.

here's code :

<?xml version="1.0" encoding="utf-8"?> <mx:application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" minwidth="955" minheight="600"                 >      <mx:script>         <![cdata[             import mx.events.flexevent;              private var rendererfactory:classfactory;              protected function btn_clickhandler(event:mouseevent):void             {                 setfilterwordinrenderer();             }               protected function application1_creationcompletehandler(event:flexevent):void             {                 setfilterwordinrenderer();             }              private function setfilterwordinrenderer():void             {                 if(!rendererfactory)                     rendererfactory =  new classfactory(customitemrenderer)                  trace("reached setfilterwordinrenderer");                  col1.itemrenderer = rendererfactory;                 col2.itemrenderer = rendererfactory;             }          ]]>     </mx:script>      <mx:button id="btn" label="highlight" click="btn_clickhandler(event)"/>     <mx:datagrid id="dtg" width="378" height="496">         <mx:dataprovider>             <mx:xmllist id="datxml" xmlns="">                 <value id='test1'>abc</value>                 <value id='test2'>sadad</value>                 <value id='23'>ytuyt</value>                 <value id='24'>uytuty</value>                 <value id='62'>erewewwer</value>                 <value id='72'>tefcvsrwert</value>                 <value id='28'>uiiyui</value>                 <value id='82'>tryry</value>                 <value id='28'>iouoo</value>                 <value id='test1'>abc</value>                 <value id='test2'>sadad</value>                 <value id='23'>ytuyt</value>                 <value id='24'>uytuty</value>                 <value id='62'>erewewwer</value>                 <value id='72'>tefcvsrwert</value>                 <value id='28'>uiiyui</value>                 <value id='82'>tryry</value>                 <value id='28'>iouoo</value>                 <value id='test1'>abc</value>                 <value id='test2'>sadad</value>                 <value id='23'>ytuyt</value>                 <value id='24'>uytuty</value>                 <value id='62'>erewewwer</value>                 <value id='72'>tefcvsrwert</value>                 <value id='28'>uiiyui</value>                 <value id='82'>tryry</value>                 <value id='28'>iouoo</value>                 <value id='test1'>abc</value>                 <value id='test2'>sadad</value>                 <value id='23'>ytuyt</value>                 <value id='24'>uytuty</value>                 <value id='62'>erewewwer</value>                 <value id='72'>tefcvsrwert</value>                 <value id='28'>uiiyui</value>                 <value id='82'>tryry</value>                 <value id='28'>iouoo</value>             </mx:xmllist>         </mx:dataprovider>         <mx:columns>             <mx:datagridcolumn id="col1" headertext="col1" datafield="@id"/>             <mx:datagridcolumn id="col2" headertext="col2" datafield="*"/>         </mx:columns>     </mx:datagrid> </mx:application> 

customitemrenderer.mxml

<?xml version="1.0" encoding="utf-8"?> <mx:hbox xmlns:mx="http://www.adobe.com/2006/mxml"          implements="mx.controls.listclasses.idropinlistitemrenderer"         >     <mx:script>         <![cdata[             import mx.collections.arraycollection;             import mx.controls.datagrid;             import mx.controls.label;             import mx.controls.datagridclasses.datagridlistdata;             import mx.controls.listclasses.baselistdata;              private var mylabel:label;               [bindable]             private var _listdata:baselistdata;              public function listdata() : baselistdata             {                 return _listdata;             }             public function set listdata( value:baselistdata ) : void             {                 _listdata = value;             }              override public function set data(value:object):void              {                 if(!value)                     return;                 super.data = value;                 //set label text,using listdata , datafield make item renderer generic possible.                 if(this.mylabel == null)                     this.mylabel = new label();                 this.mylabel.text = data[datagridlistdata(listdata).datafield];                  this.addchild(this.mylabel);             }              override protected function updatedisplaylist(unscaledwidth:number, unscaledheight:number):void {                  super.updatedisplaylist(unscaledwidth, unscaledheight);                  var g:graphics = graphics;                 g.clear();                  var object:object = _listdata;                 if (object.rowindex == 0) { //or whatever conditions                     g.beginfill(0xffffc0);                      g.drawrect(0, 0, unscaledwidth, unscaledheight);                     g.endfill();                  }             }          ]]>     </mx:script> </mx:hbox> 

the below snapshot correct when data loaded first time:

enter image description here

but when scroll through datagrid, below color applied random rows : enter image description here

you right. problem here itemrenderer recycle issue. here _listdata instance data match visible items many item become rowindex = 0 @ time of scrolling due recyle itemrenderer.

two ways can solve problem.

1) based on data (better value based highlight)

if (data.@rowno == "0") { //or rely on data way     g.beginfill(0xffffc0);      g.drawrect(0, 0, unscaledwidth, unscaledheight);     g.endfill();  } 

but xml structure need add rowno attributes below

<value id='test1' rowno="0">abc</value> <value id='test2' rowno="1">sadad</value> <value id='23' rowno="2">ytuyt</value> 

2) based on index (better index based highlight)

to grid dataprovider. griddataprovider = xmllistcollection((owner datagrid).dataprovider); in data setter method.

if (griddataprovider.getitemindex(data) == 0) {         g.beginfill(0xffffc0);      g.drawrect(0, 0, unscaledwidth, unscaledheight);     g.endfill();  } 

below code have enough clarity (customitemrenderer.mxml).

<?xml version="1.0" encoding="utf-8"?> <mx:hbox xmlns:mx="http://www.adobe.com/2006/mxml"          implements="mx.controls.listclasses.idropinlistitemrenderer">            <mx:script>         <![cdata[             import mx.collections.xmllistcollection;             import mx.controls.datagrid;             import mx.controls.label;             import mx.controls.datagridclasses.datagridlistdata;             import mx.controls.listclasses.baselistdata;              private var mylabel:label;              [bindable]             private var _listdata:baselistdata;              [bindable]             private var griddataprovider:xmllistcollection;              public function listdata() : baselistdata             {                 return _listdata;             }             public function set listdata( value:baselistdata ) : void             {                 _listdata = value;             }              override protected function createchildren():void             {                 super.createchildren();                  this.mylabel = new label();                  this.addchild(this.mylabel);             }              override public function set data(value:object):void              {                 super.data = value;                  if(!value)                     return;                  //set label text,using listdata , datafield make item renderer generic possible.                  this.mylabel.text = data[datagridlistdata(listdata).datafield];                  griddataprovider = xmllistcollection((owner datagrid).dataprovider);                  this.invalidatedisplaylist();             }              override protected function updatedisplaylist(unscaledwidth:number, unscaledheight:number):void              {                  super.updatedisplaylist(unscaledwidth, unscaledheight);                   var g:graphics = graphics;                 g.clear();                  if (griddataprovider.getitemindex(data) == 0) { //or rely on data  //              if (data.@rowno == "0") { //or rely on data                      g.beginfill(0xffffc0);                      g.drawrect(0, 0, unscaledwidth, unscaledheight);                     g.endfill();                  }             }          ]]>     </mx:script> </mx:hbox>  

best practices: component creation goes createchildren() instead of data setter method.


Comments

Popular posts from this blog

php - SPIP: From Tag directly to an article -

jquery - isAjaxRequest always return false -

ruby on rails - In a controller spec, how to find a specific tag in the generated view? -