jeudi 18 juin 2009

How to customize a cell in a datagrid with AS3

In Flash 9, with the introduction of AS3, many components from AS2 were rewritten. But, probably due to a lack of time, Adobe dev team rewrote only some components and with less features. Well, the jump between the old and riche AS2 and the freshly baked AS3 was high anyway. I didn't use AS2 and I jumped in flash 9 with AS3, mostly because I'm a developer and not a designer, and AS3 has an object oriented structure more fitted for me. Anyway, one thing that caused me big troubles was the List and Datagrid components. Simply put, they're hard to customize without breaking the whole component. For instance, changing a List in a way it displays a movieclip with a text and checkbox instead of a standard text looks nearly impossible to do. At least, that was the feeling when I was reading the documentation from Adobe. And in a first time, because my boss want to see progression in the project, I had to reimplement a list, which was also painful, introducing bugs and lacking a lot of features. But with time, and starting to work with datagrids, I could find little by little a way to customize the datagrid with the help of ICellRenderer. Just a note about ICellRenderer. This abstract class has the mean to allow the developer to implement his own cellrenderer for lists, comboboxes and datagrids. However, the way to implement it is not documented and far from being obvious. My best luck was to google some working examples, and I ended up with to working ways of customizing a Datagrid.

How to change the background color per row value Suppose you want to color a datagrid depending on the value of a cell. In fact, suppose you have a list of items and their price like that:
Name$
Apple0.5
Bread1.99
Asparagus3.0
Banana0.8
And suppose you want to color any row in red where the price is over $1 (because it's expensive). You will need at least 2 classes:
  • a cell renderer
  • a shape that will be the red background of the cell
Let's see the cell renderer:
package {
import fl.controls.listClasses.CellRenderer;
import fl.controls.listClasses.ICellRenderer;

public class CustomCellRenderer extends CellRenderer  
  implements ICellRenderer {

public function CustomCellRenderer ():void {
super();
}

public static function getStyleDefinition():Object {
return CellRenderer.getStyleDefinition();
}

override protected function drawBackground():void {
if (_data)
if (_data.price> 1) { setStyle("upSkin", RedColor ); }
super.drawBackground();
}
}
}
You can see (in bold) that I use the column "price" of the row stored in _data to do the condition to show the color. It means that you must have a column called "price" in your data to be able to use this cell renderer. Let's see now the shape class:

package
{

import flash.display.Sprite;

public class RedColor extends Sprite

{
private var _rectangle:Sprite;
public function RedColor()
{
var _rectangle = new Sprite();
_rectangle.graphics.beginFill(0xff0000,1);
_rectangle.graphics.drawRect(0, 0, 100, 20);
_rectangle.graphics.endFill();
addChild(_rectangle);
}
}
}
The class is very simple but it can't be generic because we can't manage the instances of the class. So, I didn't find a way to set the color in the runtime and I had to create one class per color. To use those classes, simply add a column to the datagrid like that:
var nameColumn:DataGridColumn = new DataGridColumn("Name");
nameColumn.cellRenderer = CustomCellRenderer ;
_grid.addColumn(nameColumn);
This will add a column in the datagrid which will display the value name with a background red or normal depends on the value of the column price. Next time, I'll explain how to add a check box, button or movieclip in a cell and add them a custom behavior.

Aucun commentaire:

Enregistrer un commentaire