How to color Datagrid cells/rows in flex 2
I have been looking for a easy and neat way to color a single cell or a complete row in flex 2.
Google brought me two interesting links:
1. How opaqueBackground can be used to color the background of a label itemRenderer
The comment posted by Dallas at 11/10/06 8:01, shows a way of highlighting a cell. Very simple implementation - the only problem is that the background color won't react on mouseover after the opaqueBackground is set.
2. How do you change the background cell color in a DataGrid?
Shows how to implement a colored background that react upon mouseover and selection. The implementation extends a label and overrides the 'updateDisplayList' method to draw some graphics as the background.
The last solution seems to be the one I preferred - because of the ability to see mouse effects applied to the cell. But still I liked the cleen implementation of the first one.
I couldn't resist of bringing combined solution, where I extends a Label, but listens for a Event.RENDER events instead of overriding the updateDisplayList method.
Sample Application
Sourcecode
Demonstrates how to use the renderer as a drop-in and inline itemRenderer.
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="vertical" verticalAlign="middle" xmlns:tmp="component.dashboard.*"
creationComplete="init()">
<mx:Script>
private function init() : void {
myGrid.setFocus();
}
</mx:Script>
<mx:XML id="itemsXML">
<items>
<item name="Item 1" state="1" />
<item name="Item 2" state="0" />
<item name="Item 3" state="0" />
<item name="Item 4" state="1" />
<item name="Item 5" state="0" />
</items>
</mx:XML>
<mx:Style>
.centered {
text-align: center;
}
</mx:Style>
<mx:DataGrid id="myGrid" dataProvider="{itemsXML.item}" editable="true">
<mx:columns>
<mx:DataGridColumn dataField="@name" headerText="Name"
headerStyleName="centered"
itemRenderer="component.dashboard.TestItemRenderer"/>
<mx:DataGridColumn dataField="@state" headerText="Price"
textAlign="right" headerStyleName="centered">
<mx:itemRenderer>
<mx:Component>
<tmp:TestItemRenderer/>
</mx:Component>
</mx:itemRenderer>
</mx:DataGridColumn>
</mx:columns>
</mx:DataGrid>
</mx:Application>
CustomItemRenderer.as
Following is a CustomItemRenderer that can be extended to apply logic to decide if a cell is to be styled.
package dk.jacobve {
import mx.controls.Label;
import mx.controls.DataGrid;
import mx.controls.dataGridClasses.*;
import mx.events.FlexEvent;
import flash.events.Event;
public class CustomItemRenderer extends Label {
public function CustomItemRenderer {
//listen for render events
addEventListener(Event.RENDER, renderListener);
}
public function styleIt() : Boolean {
return false;
}
public function styleTrue() : void {
}
public function styleFalse() : void {
}
protected function renderListener(event:Event) : void {
if (listData != null) {
var grid:DataGrid = DataGrid(DataGridListData(listData).owner);
if (!grid.isItemHighlighted(data) && grid.selectedItem != data) {
if (styleIt()) {
styleTrue();
} else {
styleFalse();
}
} else {
styleFalse();
}
}
}
}
}
CustomItemRenderer extension
Shows an implementation using E4X on a xml data element to deside if the cell is to be colored red.
package dk.jacobve {
import mx.controls.Label;
import mx.controls.DataGrid;
import mx.controls.dataGridClasses.*;
import mx.events.FlexEvent;
import flash.events.Event;
public class TestItemRenderer extends CustomItemRenderer {
public override function styleIt() : Boolean {
return data.@state == "0";
}
public override function styleTrue() : void {
this.opaqueBackground = 0x33CC33;
}
public override function styleFalse() : void {
this.opaqueBackground = null;
}
}
}