You can create custom item renderers and item editors to
control the display of the cells of the Spark DataGrid and
Grid controls. You can also create custom item renderers for the
header cells of each column of the grid.
You set a custom renderer or editor for each column of the grid.
Use the GridColumn.itemRenderer, GridColumn.itemEditor,
and GridColumn.headerRenderer properties to specify
your custom renderer or editor.
You typically create custom item renderers and item editors in
MXML. However, for the highest performance, create them in ActionScript.
The IGridItemRenderer and IGridItemEditor interfaces
Item and header renderers must implement the IGridItemRenderer interface. Item
editors must implement the IGridItemEditor interface.
The following table describes these interfaces:
Interface
Implemented by
Notes
IGridItemRenderer
Custom item and header renderers
All custom item and header renderers must
implement the IGridItemRenderer interface. The base interface of
IGridItemRenderer is IDataRenderer, the interface implemented by
item renderers for the Spark list-based controls.
IGridItemEditor
Custom item editors
All custom item editors must implement the
IGridItemEditor interface. The base interface of IGridItemEditor
is IDataRenderer.
Using the predefined item renderers
When using the DataGrid control,
you want to ensure the highest performance possible. One of the
main factors affecting performance is the time required to render
of each visible cell of the grid. Therefore, you want your item
renderers to perform at the highest level.
Flex defines several item renderers that you can use to achieve
high performance with the DataGrid control. By default, the DataGrid
control uses the DefaultGridItemRenderer renderer. This renderer
is written in ActionScript to provide good performance across all
platforms.
The following table describes the item renderer classes that
ship with Flex:
The default item renderer that displays
the cell data in a text label using the UIFTETextField control.
This class is not intended to be extended. Create a custom item
renderer based on the GridItemRenderer class.
Because it
supports the Flash Text Engine (FTE), this item render also supports bidirectional
text.
Optimized for deployment on Microsoft Windows.
For Windows, it provides improved performance over the DefaultGridItemRenderer.
For other operating systems, use DefaultGridItemRenderer for best
performance.
Because it is based on the TextField component,
this item renderer does not support bidirectional text.
The base class for custom item renderers.
This class implements the IGridItemRenderer interface.
Creating an item renderer for a Spark DataGrid
Item renderers for the Spark list-based controls, such
as List, must implement the IDataRenderer interface. Item renderers
for the Spark DataGrid must
implement the IGridItemRenderer interface,
which is derived from the IDataRenderer interface. Therefore, the
process of creating an item renderer for the DataGrid is similar
to creating one for the List control.
An item renderer is associated with a column of the DataGrid
control. The item renderer then controls the appearance of each
cell in the column. However, each item renderer has access to the
data item for an entire row of the DataGrid control. Use the data property
of the item renderer to access the data item.
By accessing the data item for the entire row, the item renderer
can display multiple data fields, or display a single value created
from multiple fields. For example, each row of the data provider
for the DataGrid control in the following example contains four
fields:
<?xml version="1.0" encoding="utf-8"?>
<!-- dpcontrols\sparkdpcontrols\SparkDGComplexIR.mxml -->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
width="450" height="450">
<fx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
// Data includes URL to album cover.
[Bindable]
private var initDG:ArrayCollection = new ArrayCollection([
{Artist:'Pavement', Album:'Slanted and Enchanted',
Price:11.99, Cover:'assets/slanted.jpg'},
{Artist:'Pavement', Album:'Brighten the Corners',
Price:11.99, Cover:'assets/brighten.jpg'}
]);
]]>
</fx:Script>
<s:DataGrid id="myGrid"
dataProvider="{initDG}"
variableRowHeight="true">
<s:columns>
<s:ArrayList>
<s:GridColumn dataField="Artist"/>
<s:GridColumn dataField="Album" itemRenderer="myComponents.DGComplexIR"/>
<s:GridColumn dataField="Price"/>
</s:ArrayList>
</s:columns>
</s:DataGrid>
</s:Application>
The executing SWF file for the previous example is shown below:
However, the DataGrid control only defines three columns. It
then uses the DGComplexIR.mxml item renderer to display the Album
and Cover fields in a single column. The item render is shown below:
Notice how the item renderer uses the data property
of the item renderer to access the data item that corresponds to
the entire row of the DataGrid control.
Creating inline renderers
In the previous example, the item renderer was defined
in a file separate from the main application file. You can define
inline item renderers for the DataGrid control.
By using an inline item renderer, your code can all be defined in
a single file. To define an inline item renderer, you use the <fx:Component> tag.
For example using inline item renderers, see Defining an inline item renderer for a Spark container.
The following example creates an inline item renderer by using
the Spark Label control:
<?xml version="1.0" encoding="utf-8"?>
<!-- dpcontrols\sparkdpcontrols\SparkDGStyledIR.mxml -->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
width="450" height="450">
<fx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
// Data includes URL to album cover.
[Bindable]
private var initDG:ArrayCollection = new ArrayCollection([
{Artist:'Pavement', Album:'Slanted and Enchanted',
Price:11.99, Cover:'../assets/slanted.jpg'},
{Artist:'Pavement', Album:'Brighten the Corners',
Price:11.99, Cover:'../assets/brighten.jpg'}
]);
]]>
</fx:Script>
<s:DataGrid id="myGrid"
dataProvider="{initDG}"
variableRowHeight="true">
<s:columns>
<s:ArrayList>
<s:GridColumn dataField="Artist">
<s:itemRenderer>
<fx:Component>
<s:GridItemRenderer>
<s:Label id="labelDisplay" fontSize="24"/>
</s:GridItemRenderer>
</fx:Component>
</s:itemRenderer>
</s:GridColumn>
<s:GridColumn dataField="Album"/>
<s:GridColumn dataField="Price"/>
</s:ArrayList>
</s:columns>
</s:DataGrid>
</s:Application>
The executing SWF file for the previous example is shown below:
Creating a header renderer for a Spark DataGrid
The DataGridSkin class
uses the GridColumnHeaderGroup component
to control the display of the column headers. The GridColumnHeaderGroup
component displays a row of headers cells, where the vertical edges
of the header cells are aligned with the grid columns.
The GridColumnHeaderGroup component arranges header renderer
instances in a row, where the left and right edge of each renderer
match the corresponding column. The renderers' height is the maximum
preferred height for all of the displayed header renderers.
Like the Grid control and item renderers, the GridColumnHeaderGroup
class only creates as many column header renderers and separators
as are visible. Renderers and separators that have been scrolled
out of view are recycled.
By default, the GridColumnHeaderGroup component uses the spark.skins.spark.DefaultGridHeaderRenderer
class as the header renderer. To create a custom header renderer,
define the renderer in MXML or ActionScript. Header renderers must
implement the IGridItemRenderer interface.
Then, use the Grid.headerRenderer property to
specify to use the custom renderer for the column.
Creating an item editor for a Spark DataGrid
The DataGrid control
includes an editable property that you set to true to
let users edit grid cells. By default, the value of the editable property
is false, which means that you cannot edit the
cells.
For a DataGrid control, setting the editable property
to true enables editing for all columns of the
grid. You can disable editing for any column by setting the GridColumn.editable property
to false.
Item editing is cell based. To edit a cell, first select the
cell or cell row, depending on the selection mode of the grid. Then
select the cell to edit. If editing is enabled, an item editor appears
over the selected cell.
Note: While an item editor is associated with a single cell,
the editor actually has access to the data provider element for
the entire row of the selected cell. Therefore, the item editor
can access and modify any data for the row.
All item editors must implement the IGridItemEditor interface.
The GridItemEditor class
implements the IGridItemEditor interface. GridItemEditor also adds the value property
that you can use to pass data to and from the item editor. Most
custom item editors are created as subclasses of GridItemEditor.
The two most important questions when dealing with an item editor
are:
How do you pass data to the item editor?
Use
the bindable GridItemEditor.value property to pass
data to the item editor. The data type of the value property
is Object, so you can use it to pass a single value to the item
editor, or you can use it to pass multiple items as fields of the
Object.
The GridItemEditor class implements the value property
as a setter and a getter method. When the item editor is created,
Flex calls the setter method, passing the cell data from the data
provider item for the row. Typically, you override the setter method
in your item editor to initialize any items in the item editor from
the cell data. The value property only exists while
the item editor is open.
To access the data provider element
for the entire row, use the data property of the
item renderer.
How do you pass data back to the DataGrid control from the
item editor?
Use the GridItemEditor.value property
to pass data back to the control. Typically, in your item editor
you override the getter method for the value property
to return any results back to the DataGrid control. The DataGrid
control writes the returned value to the data field of the data provider
element for the row that corresponds to the edited cell.
The
item editor uses the IGridItemEditor.save() method
to write the value property to the data provider
of the DataGrid control. You can override the save() method
to control how the value property is written to
the data provider. For example, the item editor might return multiple
values that you want to write to multiple fields of the data provider
element for the row. Override the save() method
in this situation to update the data provider.
Using the predefined item editors
Flex ships with two item editors that you can use in your
application. The following table describes these item editor classes:
The executing SWF file for the previous example is shown below:
The item editing process
The following steps describe the lifecycle of an item editor:
An editing session begins in response to a user gesture,
such as the user clicking a selected cell. You can also make an
explicit call to the DataGrid.startItemEditorSession() method
to start the editing session.
Before the item editor appears, the DataGrid dispatches the gridItemEditorSessionStarting event.
You
can cancel the editing session by calling the preventDefault() method
in the event handler for the gridItemEditorSessionStarting event.
Flex sets the rowIndex, column,
and data properties of the item editor. The data property
contains the data provider item for the entire row.
Flex
sets the value property of the item editor to the
value of the field in the data provider element that corresponds
to the cell being edited.
Flex calls the IGridItemEditor.prepare() method.
When
the prepare() method is called, the editor's size
and location have been set and the editor's layout has been validated.
You can override the prepare() method to make any
final modifications to the editor, such as modifying its visual
characteristics or attaching event handlers.
Flex makes the editor visible by setting its visible property
to true.
The DataGrid dispatches the gridItemEditorStart event.
When the item editor is first displayed, it is given keyboard
focus and its setFocus() method is called. You
typically override the setFocus() method of the
item editor to shift the focus to a specific component in the item
editor.
The user interacts with the editor.
The edit session ends when the user presses the Enter key
to save the data, or the Escape key to cancel the edit. The session
also ends, and the data is saved, when the users clicks outside
the editor, or the editor loses keyboard focus.
If the editing
session is saved, Flex calls the IGridtemEditor.saved() method
to write the value property back to the data provider.
You
can end the editing sessions programmatically by calling the DataGrid.endEditorSession() method.
Flex calls the IGridtemEditor.discard() method.
Override
the discard() method to reverse any settings you
made in the prepare() method, such as removing
event handles, or perform any other cleanup.
The DataGrid dispatches either the gridItemEditorSessionSave or gridItemEditorSessionCancel event.
Example custom item editor
The following example shows a DataGrid control
that uses and item editor to let the user change the value of the
quant field of the data provider. The second column of the control
specifies to use the DGNumStepperEditor.mxml item editor:
The executing SWF file for the previous example is shown below:
The DGNumStepperEditor.mxml item editor defines a NumericStepper
control to set an integer value. The item editor overrides the setter
method for the value property to initialize the
NumericStepper control with the current value of the cell.
The override of the getter method for the value property
returns the current value of the NumericStepper control. The save() method
updates the data provider element for the row of the grid with this
value. The DGNumStepperEditor.mxml item editor is shown below:
<?xml version="1.0" encoding="utf-8"?>
<!-- dpcontrols\sparkdpcontrols\myComponents\DGNumStepperEditor.mxml -->
<s:GridItemEditor xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx">
<fx:Script>
<![CDATA[
// Override the setter to initialize the NumericStepper control
// with the cell data.
override public function set value(newValue:Object):void {
ns.value = newValue as Number;
}
// Override the getter to return the current value of
// the NumericStepper control.
// The save() method updates the data provider element for the
// row of the grid with this value.
override public function get value():Object {
return ns.value;
}
// Override setFocus() to shift focus to the NumericStepper.
override public function setFocus():void {
ns.setFocus();
}
]]>
</fx:Script>
<s:NumericStepper id="ns" width="100%"
fontWeight="bold"/>
</s:GridItemEditor>
Keyboard and mouse shortcuts with item editors for the Spark DataGrid
The following table describes how the item editor responds
to user interaction:
User interaction
Response
F2
If cell selection mode is enabled, edit
the cell indicated by the caret.
If row selection mode is
enabled, and a cell has not been edited before, edit the first visible
cell in the row indicated by the caret. Otherwise edit the cell
in the last edited column in the caret row.
Enter
Save the editor's value and close the editor.
Esc
Cancel the editing session by closing the
editor without saving the value.
Tab
Save the editor's value, close the editor,
and open the editor in the next column that is editable.
Shift+Tab
Save the editor's value, close the editor,
and open the editor in the first previous column that is editable.
Ctrl+.
Cancel the editing session by closing the
editor without saving the value.
Ctrl+Enter
Save the editor's value, close the editor,
and move selection to the same column in the next row.
Ctrl+Shift+Enter
Save the editor's value, close the editor,
and move selection to the same column in the previous row.
Single mouse click
Open the editor in response to a single
click on the selected cell. The cell must already be selected.
If
the Shift or Ctrl key is pressed when the click occurs, then the
editor does not open because the Shift and Ctrl keys are used to
modify the selection.