ActionScript - Access List/DataProvider From Custom CellRenderer?

There are multiple ways to do this Here is a very hacky solution : Use an icon, and have that icon dispatch a close event The idea is you'll place a custom MovieClip in each list cell as icon. That icon will dispatch an event with the index of the cell clicked so you can remove it 1st step : Make a basic custom event to pass cell index through: package{ import flash.events. Event; public class CloseEvent extends Event{ public static const CLOSE:String = 'close'; public var index:int; public function CloseEvent(type:String,bubbles:Boolean = true,cancelable:Boolean=true){ super(type,bubbles,cancelable); } } } 2nd step: : Draw a close icon or something, convert it to MovieClip and Export for Actionscript 3rd step : Add the event listener to dispatch the custom event when the close icon is clicked Inside the close icon Movie Clip I've placed the following actions: import fl.controls.listClasses.

CellRenderer; //setup click buttonMode = true; if(parent) parent. MouseChildren = true; addEventListener(MouseEvent. MOUSE_DOWN,dispatchClose); //setup event var closeEvent:CloseEvent = new CloseEvent(CloseEvent.

CLOSE,true); if(parent) closeEvent. Index = CellRenderer(parent).listData. Index; //listen to click and pass on function dispatchClose(event:MouseEvent):void { dispatchEvent(closeEvent); } Very basic stuff, listen for mouse down, create an event and set the index and dispatch that event on click.

The icon is added to a cell renderer, therefor the cell render is it's parent which it has a listData property among others, which holds the index of the cell So here's how the test snippet looks: import fl.data. DataProvider; var dp:DataProvider = new DataProvider(); for(var i:int = 0 ; I DataProvider = dp; addEventListener(CloseEvent. CLOSE,deleteItem); function deleteItem(event:CloseEvent):void { ls.

RemoveItemAt(event. Index); } Since the CloseEvent bubbles, we can catch it from outside the cell renderer's icon and tell the list to remove the item at that index. It's possible to do that within the icon, but it will be necessary to 'climb' up the hierarchy all the way to the list, and it's pretty hacky already I did this because, I was probably as lazy as @TheDarkIn1978 :P to implement the ICellRenderer functions.

Then I looked at question code again and didn't understand why the custom cell extends a Sprite, when CellRenderer already implements the ICellRenderer functions already So here is my attempt to do it in a less hacky manner: package{ import fl.controls. *; import fl.controls.listClasses. *; import fl.data.

*; import flash.events. *; public class SCListCell extends CellRenderer implements ICellRenderer{ protected var closeButton:Button; protected var closeEvent:CloseEvent; override protected function configUI():void { super.configUI(); closeButton = new Button(); closeButton. Label = 'x'; closeButton.

ButtonMode = true; closeButton. SetSize(30,20); closeButton.drawNow(); closeButton. AddEventListener(MouseEvent.

CLICK,close); addChild(closeButton); closeEvent = new CloseEvent(CloseEvent. CLOSE); } private function close(event:MouseEvent):void{ closeEvent. Index = listData.

Index; dispatchEvent(closeEvent); } override protected function drawLayout():void{ mouseChildren = true; closeButton. X = width-closeButton. Width; } } } Used the same CloseEvent to pass the index, and the custom cell has direct access to the listData object to fetch the index, so the sample snippet looks like this: import fl.data.

DataProvider; var dp:DataProvider = new DataProvider(); for(var i:int = 0 ; I AddItem({label:'item'+(i+1)}); ls. DataProvider = dp; addEventListener(CloseEvent. CLOSE,deleteItem); function deleteItem(event:CloseEvent):void { ls.

RemoveItemAt(event. Index); } ls. SetStyle('cellRenderer',SCListCell) So to answer your question : how can I properly access the parent List object from its custom cell renderer?

You can use the listData property of the cell renderer. You can if you want to, but it means going up a few levels: package{ import fl.controls. *; import fl.controls.listClasses.

*; import fl.data. *; import flash.events. *; public class SCListCell extends CellRenderer implements ICellRenderer{ protected var closeButton:Button; override protected function configUI():void { super.configUI(); closeButton = new Button(); closeButton.

Label = 'x'; closeButton. ButtonMode = true; closeButton. SetSize(30,20); closeButton.drawNow(); closeButton.

AddEventListener(MouseEvent. CLICK,close); addChild(closeButton); } private function close(event:MouseEvent):void{ List(this.parent.parent. Parent).

RemoveItemAt(listData. Index); } override protected function drawLayout():void{ mouseChildren = true; closeButton. X = width-closeButton.

Width; } } } Which leaves the list creation part as simple as: import fl.data. DataProvider; var dp:DataProvider = new DataProvider(); for(var i:int = 0 ; I DataProvider = dp; ls. SetStyle('cellRenderer',SCListCell) CloseEvent isn't needed in this case.

There are multiple ways to do this. Here is a very hacky solution: Use an icon, and have that icon dispatch a close event. The idea is you'll place a custom MovieClip in each list cell as icon.

That icon will dispatch an event with the index of the cell clicked so you can remove it. 1st step: Make a basic custom event to pass cell index through: package{ import flash.events. Event; public class CloseEvent extends Event{ public static const CLOSE:String = 'close'; public var index:int; public function CloseEvent(type:String,bubbles:Boolean = true,cancelable:Boolean=true){ super(type,bubbles,cancelable); } } } 2nd step:: Draw a close icon or something, convert it to MovieClip and Export for Actionscript 3rd step: Add the event listener to dispatch the custom event when the close icon is clicked.

Inside the close icon Movie Clip I've placed the following actions: import fl.controls.listClasses. CellRenderer; //setup click buttonMode = true; if(parent) parent. MouseChildren = true; addEventListener(MouseEvent.

MOUSE_DOWN,dispatchClose); //setup event var closeEvent:CloseEvent = new CloseEvent(CloseEvent. CLOSE,true); if(parent) closeEvent. Index = CellRenderer(parent).listData.

Index; //listen to click and pass on function dispatchClose(event:MouseEvent):void { dispatchEvent(closeEvent); } Very basic stuff, listen for mouse down, create an event and set the index and dispatch that event on click. The icon is added to a cell renderer, therefor the cell render is it's parent which it has a listData property among others, which holds the index of the cell. So here's how the test snippet looks: import fl.data.

DataProvider; var dp:DataProvider = new DataProvider(); for(var i:int = 0 ; I CLOSE,deleteItem); function deleteItem(event:CloseEvent):void { ls. RemoveItemAt(event. Index); } Since the CloseEvent bubbles, we can catch it from outside the cell renderer's icon and tell the list to remove the item at that index.It's possible to do that within the icon, but it will be necessary to 'climb' up the hierarchy all the way to the list, and it's pretty hacky already.

I did this because, I was probably as lazy as @TheDarkIn1978 :P to implement the ICellRenderer functions. Then I looked at question code again and didn't understand why the custom cell extends a Sprite, when CellRenderer already implements the ICellRenderer functions already.So here is my attempt to do it in a less hacky manner: package{ import fl.controls. *; import fl.controls.listClasses.

*; import fl.data. *; import flash.events. *; public class SCListCell extends CellRenderer implements ICellRenderer{ protected var closeButton:Button; protected var closeEvent:CloseEvent; override protected function configUI():void { super.configUI(); closeButton = new Button(); closeButton.

Label = 'x'; closeButton. ButtonMode = true; closeButton. SetSize(30,20); closeButton.drawNow(); closeButton.

AddEventListener(MouseEvent. CLICK,close); addChild(closeButton); closeEvent = new CloseEvent(CloseEvent. CLOSE); } private function close(event:MouseEvent):void{ closeEvent.

Index = listData. Index; dispatchEvent(closeEvent); } override protected function drawLayout():void{ mouseChildren = true; closeButton. X = width-closeButton.

Width; } } } Used the same CloseEvent to pass the index, and the custom cell has direct access to the listData object to fetch the index, so the sample snippet looks like this: import fl.data. DataProvider; var dp:DataProvider = new DataProvider(); for(var i:int = 0 ; I CLOSE,deleteItem); function deleteItem(event:CloseEvent):void { ls. RemoveItemAt(event.

Index); } ls. SetStyle('cellRenderer',SCListCell); So to answer your question: how can I properly access the parent List object from its custom cell renderer? You can use the listData property of the cell renderer.

You can if you want to, but it means going up a few levels: package{ import fl.controls. *; import fl.controls.listClasses. *; import fl.data.

*; import flash.events. *; public class SCListCell extends CellRenderer implements ICellRenderer{ protected var closeButton:Button; override protected function configUI():void { super.configUI(); closeButton = new Button(); closeButton. Label = 'x'; closeButton.

ButtonMode = true; closeButton. SetSize(30,20); closeButton.drawNow(); closeButton. AddEventListener(MouseEvent.

CLICK,close); addChild(closeButton); } private function close(event:MouseEvent):void{ List(this.parent.parent. Parent). RemoveItemAt(listData.

Index); } override protected function drawLayout():void{ mouseChildren = true; closeButton. X = width-closeButton. Width; } } } Which leaves the list creation part as simple as: import fl.data.

DataProvider; var dp:DataProvider = new DataProvider(); for(var i:int = 0 ; I AddItem({label:'item'+(i+1)}); ls. DataProvider = dp; ls. SetStyle('cellRenderer',SCListCell); CloseEvent isn't needed in this case.HTH.

Thanks for the lengthy response. The reason why i'm extending Sprite and implementing ICellRenderer instead of simply extending CellRenderer is because, as far as I know, it's the only way to really have full control over a custom cell: basically a sprite with a full, unlimited display list parenting any display object and the ability to position them anywhere. For example, if I simply extend CellRenderer I don't believe I could have 3 textFields, a few checkBoxes or buttons and be able to place them wherever I want them using plain x and y.

– TheDarkIn1978 Dec 15 '10 at 2:20 this method is written about here: "Use A Symbol To Define A CellRenderer": help.adobe. Com/en_US/ActionScript/3.0_UsingComponentsAS3/… – TheDarkIn1978 Dec 15 '10 at 2:22 @TheDarkIn1978 I see, that makes sense. If it helps, try extending UIComponent as it already implements setStyle, setSize and a few others, might be handy.

– George Profenza 8 Dec3 at 9:38 after spending days trying to implement my own ICellRenderer i've realized that there are some things going on in the background that I seriously do not understand. In both extending the CellRenderer or using a symbol to define a cell renderer, adding a shape or sprite with graphics to the display list of the cell really kills performance with touch (automatic) scrolling. It seems I can temporarily remedy the lag by calling list.invalidateList() often, but that seems like such a dirty hack.

Any ideas what's happening? – TheDarkIn1978 Dec 23 '10 at 10:37 @TheDarkIn1978 How complex are the graphics? If they're vector heavy, it could impact performance, as the cells get redrawn on rollover/rollout/click/etc.You could either try to enable cacheAsBitmap for the background or export an image and use an image instead of complex vectors, if that's the case – George Profenza 8 Dec3 at 11:10.

Ugh! The answer was in front of me the whole time! Next time remind me to check the docs: List(listData.

Owner) fl.controls.listClasses.ListData.owner.

I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.

Related Questions