1. Trang chủ
  2. » Công Nghệ Thông Tin

Tài liệu Flash Builder 4 and Flex 4 Bible- P14 docx

50 507 0
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Tiêu đề Using Advanced List Controls
Trường học University of the People
Chuyên ngành Flex 4 and Flash Builder 4
Thể loại Giáo trình
Định dạng
Số trang 50
Dung lượng 906,26 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

In an MX DataGrid control, an item renderer or editor is used in a specific column, so the itemRenderer and itemEditor properties are implemented in the DataGridColumn architec-component

Trang 1

A DataGridColumn with custom label formatting

Using a dynamic data field

As I described previously, the custom formatting function for a DataGridColumn requires an argument that references the DataGridColumn that is calling the function The purpose of this argument is to enable you to determine the data field of the current data item dynamically

For example, if the data provider’s data items have phone values in two different properties and you want to format them both with the same logic, you can identify the property you want to for-mat with the array-style expression item[column.dataField] The dataField property of the DataGridColumn returns the name of the property currently being processed, so you need only one custom function to format as many data properties as needed:

private function getPhoneLabel(item:Object, column:DataGridColumn):String

{ var dataValue:String = item[column.dataField];

var pattern:RegExp = /-/g;

var phoneValue:String = dataValue.replace(pattern, “”);

return formatter.format(phoneValue);

}

Trang 2

Debugging a custom formatting function

It can be instructive to add a trace() statement to the body of a custom formatting function As you scroll up and down in a DataGrid, the trace statement in the custom function is executed each time the data grid column has to be formatted:

private function getPhoneLabel(item:Object, column:DataGridColumn):String

{ var dataValue:String = item[column.dataField];

var pattern:RegExp = /-/g;

var phoneValue:String = item.phone.replace(pattern, “”);

trace(“original value: “ + dataValue + “, “ + “formatted value: “ + formatter.format(phoneValue));

return formatter.format(phoneValue);

}

Figure 20.8 shows the resulting output in Flash Builder’s Console view when the application is run

in debug mode The Console view displays the trace statements continuously as you scroll up and down in the DataGrid

As a result, you can populate the DataGrid and other list controls with significant amounts of data without causing Flash Player to bog down or overload its memory usage When you run the application described pre- viously with trace statements, try scrolling up and down You’ll notice that the function is called frequently as you scroll, and the existing visual objects are updated with new data n

Advanced Item Renderers and Editors

As described in Chapter 18, all list controls support the custom item renderer and editor tures In an MX DataGrid control, an item renderer or editor is used in a specific column, so the itemRenderer and itemEditor properties are implemented in the DataGridColumn

architec-component

Trang 3

Just as with the List control, item renderer and editor components for the DataGridColumn

can be declared in three ways:

l Drop-in renderers These are visual components that you assign to a list control without

any changes to the renderer component’s default property or style settings

l Inline renderers These are components you define and nest within an MXML declaration

of the list control

l Component renderers These are separate visual components that you define as MXML

components or ActionScript classes and assign to the list control’s itemRenderer erty in an MXML declaration You also can assign a component renderer at runtime with ActionScript code by using the mx.core.ClassFactory class (described next)

prop-Cross-Reference

For more information on the three types of item renderer declarations, see Chapter 19 n

At runtime, the DataGridColumn creates an instance of the component and passes its data vider’s current data item as the renderer object’s data property Within the custom component, whether declared inline or as a separate component, you use the data object’s properties with either ActionScript statements or binding expressions to populate visual objects and create your custom presentation

pro-Using the dataChange event

In the following example, a DataGrid component displays contact information from the

contacts.xml file In the first column of the DataGrid, the contact’s first and last names are displayed as a single concatenated string This task can be easily handled with a custom label formatting function:

private function getNameLabel(item:Object, column:DataGridColumn):String

{ return item.firstname + “ “ + item.lastname;

}

In the second column, the DataGrid will display the contact’s full address, formatted as a single

Text control using HTML markup for bold and other formatting To handle this requirement, you can use the dataChange event to update a custom component’s display at runtime This event is dispatched within the custom component whenever the value of its data property is updated You can respond to the event by explicitly updating the custom component’s nested objects as needed

The custom component in Listing 20.9 is extended from the MX Text component When the component’s dataChange event is dispatched, it responds by updating its own htmlText prop-erty with the data object’s new property values

Trang 4

</fx:Script>

</mx:Text>

On the Web

The code in Listing 20.9 is available in the Web site files as AddressRenderer.mxml in the chapter20

project’s renderers package n

The application in Listing 20.10 uses the custom component as an item renderer to display plete formatted address information in the DataGrid control’s second column Notice that the

com-DataGrid control’s selectable property is set to false This makes it easier for the user to select the custom component’s text value for copying Also, its variableRowHeight property is set to true to enable the DataGrid columns to adjust their height as needed

return item.firstname + “ “ + item.lastname;

Trang 5

} ]]>

</fx:Script>

<fx:Declarations>

<fx:Model id=”contactData” source=”data/contacts.xml”/>

<s:ArrayList id=”contactAC” source=”{contactData.row}”/>

</fx:Declarations>

<mx:DataGrid id=”contactGrid” dataProvider=”{contactAC}”

selectable=”false” variableRowHeight=”true” rowCount=”5”>

FIGURE 20.9

A custom item renderer using the dataChange event

Trang 6

Using Spark item renderers

MXAdvancedDataGridItemRenderer These Spark-based components are designed to be used as the root elements for custom item renderers used by the MX DataGrid and

AdvancedDataGrid controls They enable you to use vector graphics and advanced text ing, even though the containing component is an MX-based control

render-You can create a new item renderer for a DataGrid by following these steps:

1 In the Package Explorer view, right-click on the package in which you want to

cre-ate a new renderer component.

2 Choose New ➪ MXML Item Renderer.

3 Select the template Item Renderer for MX DataGrid.

4 Click Finish to create the new item renderer component

Listing 20.11 shows a completed Spark item renderer for a DataGridColumn that incorporates a radial gradient background defined with an FXG graphic and Spark-based Label controls to dis-play the text

<s:Label text=”{data.city}, {data.state}”/>

<s:Label fontWeight=”bold” text=”{data.phone}”/>

</s:VGroup>

</s:MXDataGridItemRenderer>

Trang 7

A DataGrid with a Spark-based item renderer with FXG graphics

Using item editors

Like an item renderer, an item editor is a custom component that you display instead of the default label in a DataGridColumn cell An item editor, however, is always an interactive control that enables the user to make changes to the data it represents As with item renderers, you can declare

an item editor using a drop-in, inline, and component syntax

Before you can use an item editor, the DataGrid must have its editable property set to true When you do this, the DataGrid automatically displays an item editor in any cell the user clicks

The default item editor is the TextInput control, so when the user clicks into an editable cell, he’s presented with a TextInput that enables him to change the data When he clicks or tabs out of the cell, the new data is saved to the DataGrid component’s data provider in application memory

When you set the DataGrid component’s editable property to true, all its columns are matically editable Each DataGridComponent has an editable property as well; you stop edit-ing of any particular column by setting its editable property to false

Trang 8

auto-In the following code, the DataGrid is editable, but editing is prevented in the firstname and

lastname columns As a result, only the data in the phone column can be changed by the user:

<mx:DataGrid id=”contactGrid” dataProvider=”{contactAC}”

If you apply a labelFunction to a column that’s also editable and uses the default item editor, the user will

be editing the value returned from the labelFunction and not the column’s original data n

Using drop-in item editors

To use a component as a drop-in item editor for an MX DataGrid control, it must implement the

IDropInListItemRenderer interface, and it must be interactive, enabling the user to make changes to data Only a small number of components in the Flex SDK qualify on both counts; they include:

To declare a drop-in editor in a DataGridColumn, you assign the component to the

DataGridColumn component’s itemEditor (if you want to see the component appear only when the user clicks a cell to edit it), or to its itemRenderer (if you want to see it appear on all rows) In either case, you assign the component by its fully qualified class name, including the package prefix:

Trang 9

Using the itemEditor and editorDataField properties

When you declare an itemEditor for a DataGridColumn, you also have to set the

DataGridColumn control’s editorDataField property to indicate which field of the item tor component contains the value entered by the user At runtime, the changed value is transferred back to the current data object’s property (the property that’s named as the DataGridColumn

edi-component’s dataField)

For example, if you use a CheckBox control as an item editor, the editorDataField property should be set to selected For a TextInput control, editorDataField should be set to

text (the default), for a NumericStepper, it should be value, and so on

When you set the itemEditor property to a named component, that component is instantiated only when the user clicks into the cell For example, the following code indicates that a CheckBox

control should appear only when the user clicks:

<mx:DataGridColumn dataField=”selected”

itemEditor=”mx.controls.CheckBox”

editorDataField=”selected”

headerText=”” width=”50”/>

Unless the user has clicked a cell that’s editable, the column’s actual value is displayed as a label

When the user clicks in a cell, it displays the CheckBox control

Using the rendererIsEditor property

If you want the item editor component to be displayed in every row of the DataGrid, follow these steps:

1 Assign the editor component DataGridColumn component’s itemRenderer

property instead of itemEditor.

2 Set the DataGridColumn component’s rendererIsEditor property to true.

The following code causes the CheckBox control to appear in every row, regardless of whether the user has clicked into the cell:

The application in Listing 20.12 uses an itemRenderer in its first DataGrid that’s set with

rendererIsEditor to true The renderer is a drop-in component based on mx.controls

CheckBox At application startup, the initApp() method loops through the ArrayList being used as the DataGrid component’s data provider and adds a selected property to each object

That property is then both displayed and edited through the CheckBox that appears on every row

When the user clicks Show Selected, the application loops through the first data provider and locates all data items with selected set to true and adds them to a second ArrayList that’s dis-played in a separate DataGrid

Trang 10

protected var selectedData:ArrayList = new ArrayList();

protected function app_creationCompleteHandler(event:FlexEvent):void {

//Add a selected property to each data object on startup for (var i:int=0;i < collection.length; i++)

{ var contact:Object = collection.getItemAt(i);

contact.selected=false;

} } protected function button1_clickHandler(event:MouseEvent):void {

selectedData = new ArrayList();

for (var i:Number=0; i<collection.length; i++) {

if (collection.getItemAt(i).selected) {

selectedData.addItem(collection.getItemAt(i));

} } } ]]>

</fx:Script>

<fx:Declarations>

<fx:Model id=”contactData” source=”data/contacts.xml”/>

<s:ArrayList id=”collection” source=”{contactData.row}”/>

</fx:Declarations>

Trang 11

<s:HGroup>

<s:Panel title=”Available Data”>

<mx:DataGrid id=”contactGrid” dataProvider=”{collection}”

<s:Panel title=”Selected Data”>

<mx:DataGrid id=”selectedGrid” dataProvider=”{selectedData}”>

<mx:columns>

<mx:DataGridColumn dataField=”firstname” headerText=”First Name”/>

<mx:DataGridColumn dataField=”lastname” headerText=”Last Name”/>

Tip

When you allow the user to edit data through an editable DataGrid, changes are made to the data collection that’s stored in client memory If you want to save the data to a persistent data store on the server (or on the client, in the case of an Adobe AIR-based desktop application), you need to write code to transfer the changed data If the persistent data store is on the server, you can accomplish this with the Remote Procedure Call (RPC) components (HTTPService, WebService, or RemoteObject) or with the Data Management Service (if using LiveCycle Data Services) With a desktop-based application, you could use the local SQLite database that’s embedded in Adobe AIR n

Trang 12

FIGURE 20.11

A renderer displaying every row with rendererIsEditor set to true

Using inline and component editors

As with custom renderers, you can declare custom item editor components with either inline tax or as separate components The benefits of using this syntax instead of drop-in components are that you’re free to use any combination of visual controls and containers, and you can override the components’ default property and style settings

syn-For example, imagine that you wanted to use the DateField control as an item editor, but you modify its default behavior in some way You might set its editable property to true to enable the user to enter a date directly (without having to pick it from the pop-up calendar control) or restrict its available dates:

<mx:DataGridColumn dataField=”dob” editorDataField=”selectedDate”>

are transformed into instances of the ContactVO class This is critical for this example, because

Trang 13

the ContactVO class has a dob property typed as a Date, which makes it compatible with the

DateField control that is then used as the property’s editor in the DataGrid

[Bindable]

private var collection:ArrayCollection;

private function resultHandler(event:ResultEvent):void {

collection = event.result.contacts.row;

for (var i:int=0; i<collection.length; i++) {

var newContact:ContactVO = new ContactVO(collection.getItemAt(i));

collection.setItemAt(newContact, i);

} } private function getDateLabel(

item:ContactVO, column:DataGridColumn):String {

return dateFormatter.format(item.dob);

} ]]>

Trang 14

DateField control’s button, the calendar control pops up Because the DateField control’s

editable property is true, the user also can click into the TextInput portion of the

DateField and type a value directly

FIGURE 20.12

An itemEditor declared within inline syntax to enable custom properties and behaviors to be declared

Trang 15

Using List Controls with Horizontal and Tile Layout

The MX HorizontalList and TileList controls share nearly all the behaviors and ties of the DataGrid and List controls:

capabili-l Data provided to a HorizontalList or TileList is typically displayed using a tom item renderer, declared either inline or as a separate component

cus-l The change event notifies you that the user has selected a data item

l The selectedItem property returns a reference to the selected data item

l The allowMultipleSelection property enables users to select multiple data items by clicking while holding down Ctrl (or Ô on the Mac) and Shift

l As the user scrolls, existing visual objects are reused and their data is populated with the new data As with the DataGrid control, this creates a smooth scrolling experience while enabling these controls to display large amounts of data without overusing Flash Player memory

Cross-Reference

The new Spark List control’s layout property enables you to lay out the control’s data items horizontally or

in tile format If you prefer to use the new Spark skinning architecture, see the instructions for the Spark List control in Chapter 18 n

The difference between the HorizontalList and TileList controls has to do with their out As implied by their component names, the HorizontalList lays out cells in a single row, whereas the TileList lays out cells in a similar fashion to the Tile container, as a grid of objects

lay-in rows and columns

The TileList and HorizontalList controls are almost always used with custom item ers that determine the presentation of each of the list’s cells As with the other list controls, you declare the item renderer component with drop-in, inline, or component syntax

render-The application in Listing 20.14 uses an MX TileList control and an inline renderer to display the contents of an XML file that refers to image files in the project’s assets folder The renderer component uses properties of each XML <slide> element to present an Image and a Label

wrapped in a VBox container

The TileList is wrapped inside a Panel container When the user clicks in one of the

TileList control’s cells, the detail region is updated through the use of binding expressions

Trang 16

<fx:Model id=”slideModel” source=”data/slideshow.xml”/>

<s:ArrayCollection id=”slideAC” source=”{slideModel.slide}”/>

</fx:Declarations>

<s:Panel title=”My Photos” height=”430” width=”525”>

<s:layout>

<s:VerticalLayout paddingLeft=”10” paddingRight=”10”

paddingTop=”10” paddingBottom=”10”/>

</s:layout>

<mx:TileList id=”slideList” dataProvider=”{slideAC}”

Trang 17

On the Web

The code in Listing 20.14 is available in the Web site files as MXTileList.mxml in the chapter20 project n

Figure 20.13 shows the resulting application, with graphic images and their captions laid out in a gridlike format

FIGURE 20.13

An MX TileList control displaying an inline item renderer

The HorizontalList control uses the same architecture, enabling the user to scroll sideways through content In the application in Listing 20.15, the change event handler saves the current

selectedItem to a bindable Object When the item is selected, the VBox container at the tom of the application becomes visible due to its use of a binding expression in its enabled property

Trang 18

currentImage=event.target.selectedItem;

detailPanel.visible=true;

} ]]>

<fx:Model id=”slideModel” source=”data/slideshow.xml”/>

<s:ArrayCollection id=”slideAC” source=”{slideModel.slide}”/>

paddingTop=”10” paddingBottom=”10”/>

</s:layout>

<mx:HorizontalList id=”slideList” dataProvider=”{slideAC}”

width=”100%” height=”125” rowHeight=”125” columnWidth=”120”

<s:Panel id=”detailPanel” title=”Selected Photo”

width=”372” height=”320” visible=”false”>

<s:layout>

<s:VerticalLayout

Trang 19

A HorizontalList control with selected information displayed in a detail region

The Spark version of the List control supports a layout property that can be set to an instance of

HorizontalLayout or TileLayout You use ItemRenderer as the base class of its custom

Trang 20

<fx:Model id=”slideModel” source=”data/slideshow.xml”/>

<s:ArrayCollection id=”slideAC” source=”{slideModel.slide}”/>

</fx:Declarations>

<s:Panel title=”My Photos” height=”430” width=”550”>

<s:layout>

<s:VerticalLayout paddingLeft=”10” paddingRight=”10”

Trang 21

Using the AdvancedDataGrid Control

The AdvancedDataGrid control is an extended version of the DataGrid control that adds these features:

l Sorting by multiple columns

l Row- and column-based styling

l Displaying hierarchical data with an embedded Tree component

l Dynamic grouping of “flat” data into a hierarchical display

l Grouping of multiple columns under a single heading

l Multicolumn item renderers

Note

The AdvancedDataGrid control is available only as part of the Data Visualization components license This package also includes the Flex charting controls The license is sold on a per-developer basis, so there aren’t any ongoing royalties for using these controls Unlike in the Flex 2 product line, the charting and other Data Visualization components aren’t sold as stand-alone products; they’re available only as part a Flash Builder Premium license n

Hierarchical data display

As with the DataGrid, the AdvancedDataGrid control’s data provider is typically in the form

of an ArrayCollection To use the hierarchical data display feature, the objects in the data set should include at least one “grouping” property that can be used to collect and group data items based on their identical values in that property

You can display data that is already in hierarchical form, such as the data created in this ActionScript code:

var employeeAC:ArrayCollection = new ArrayCollection();

employeeAC.source = [{department:”Shipping”, children: [

{firstname:”Kevin”, lastname:”Mount”}, {firstname:”Robert”, lastname:”Lombardi”}]}, {department:”Marketing”,

Trang 22

children: [ {firstname:”Brad”, lastname:”Lang”}, {firstname:”James”, lastname:”Jaeger”}]}

];

Notice that the data is structured as an Array containing multiple Object instances, written in ActionScript shorthand notation Each Object contains a department property designed as the grouping field and an Array named children that contains additional data objects

You pass this type of data to the AdvancedDataGrid by first wrapping it in an instance of the

HierarchicalData class This class has a childrenField property that defines which field

of each object is expected to contain child objects Its default value is children, so the data described in the ActionScript code has the expected structure and field names already

Note

The AdvancedDataGrid component handles XML-based data intuitively Child XML nodes are rendered as nodes of the component’s nested Tree control n

The columns property of the AdvancedDataGrid control should contain instances of the

AdvancedDataGridColumn component Its dataField and headerText properties behave just like the DataGridColumn, and its style enables you to specify the color and font on a per-column basis

The application in Listing 20.17 uses a hierarchical data set and an AdvancedDataGrid to play grouped data

employeeAC.source = [ {department:”Shipping”,

Trang 23

children: [{firstname:”Kevin”, lastname:”Mount”}, {firstname:”Robert”, lastname:”Lombardi”}]}, {department:”Marketing”,

children: [{firstname:”Brad”, lastname:”Lang”}, {firstname:”James”, lastname:”Jaeger”}]}

];

} ]]>

Trang 24

Grouping flat data

Flat data is typically defined as a conventional ArrayCollection containing rows and columns, such as you might import into a Flex application with a call to a database query You can group this type of data structure in an AdvancedDataGrid control by wrapping it in a

GroupingCollection2 object This object contains one or more nested GroupingField

objects that define which columns or properties you want to group on

In MXML, you prepare the data like this:

<mx:GroupingCollection2 id=”gc” source=”{dataCollection}”>

The GroupingCollection2 is then passed to the AdvancedDataGrid component’s

dataProvider To make the GroupingCollection2 update its view, you must call its

refresh() method In the following code, the refresh() method is called when the grid component’s initialize event is dispatched:

Trang 25

<fx:Model id=”empModel” source=”data/employees.xml”/>

<s:ArrayCollection id=”employeeAC” source=”{empModel.row}”/>

Ngày đăng: 26/01/2014, 20:20