第4回Flex勉強会 †
テーマ †
- データプロバイダ (P257 ~ P300)
- レンダラーとラベルファンクション (P287 ~ P290)
- ViewStack?とTabNavigator? (P305 ~ P307)
日時 †
2008/2/16(土)
概要 †
資料のダウンロードはこちら
データプロバイダ (P257 ~ P300) - 詳細 †
- データプロバイダの基礎知識 - 詳細
- XMLと連携する - 詳細
- Arrayと連携する - 詳細
- ArrayとArrayCollection?の違い - 詳細
- ソート順の指定 - 詳細
- ツリーの表示 - 詳細
レンダラーとラベルファンクション (P287 ~ P290) - 詳細 †
- レンダラーとラベルファンクションの基礎知識 - 詳細
- ラベルファンクション - 詳細
- リスト系コントロール用のラベルファンクション - 詳細
- データグリッド用のラベルファンクション - 詳細
- 指定するのはあくまでもFunctionオブジェクト - 詳細
- DTOの読み取り専用プロパティで代用 - 詳細
- レンダラー - 詳細
- 既存のコントロールをレンダラーに指定 - 詳細
- インラインでレンダラーを記述 - 詳細
- MXMLでレンダラークラスを作成 - 詳細
- ActionScript?でレンダラークラスを作成 - 詳細
- データグリッド全体にレンダラーを適用 - 詳細
- ClassFactory?をレンダラーに指定 - 詳細
ViewStack?とTabNavigator? (P305 ~ P307) - 詳細 †
- ViewStack? - 詳細
- TabNavigator? - 詳細
- Accordion - 詳細
詳細 †
データプロバイダ (P257 ~ P300) †
- データプロバイダの基礎知識
- データプロバイダとは、複数の値を表示するコンポーネント(リスト系コントロールやデータグリッド)に対象となるデータを関連づける仕組み。
- 複数の値を表示するコンポーネントのdataProviderプロパティに、XMLやArrayオブジェクトを指定する。
(主にデータバインディングを使って指定する。)
- リスト系のコンポーネントには次のようなものがある。
- mx.controls.List - リスト (HTMLの複数行表示のSELECTフォームに似ている、リストに無い値をユーザーが自由に追加することは基本的にできない)
- mx.controls.ComboBox? - コンボボックス (HTMLの単一行表示のSELECTフォームに似ている、リストに無い値をユーザーが自由に追加することも基本的にできる)
- mx.controls.HorizontalList? - 横方向のリスト
- mx.controls.Tree - ツリー
- mx.controls.Menu - ポップアップメニュー
- mx.controls.ButtonBar? - ボタン(mx.controls.Button)のグループ
- mx.controls.LinkBar? - リンクボタン(mx.controls.LinkButton?)のグループ (ViewStack?の制御にも使える)
- mx.controls.ToggleButtonBar? - トグルボタン(1つだけが選択状態にできるボタン)のグループ (ViewStack?の制御にも使える)
- 関連付けたデータのどのフィールドの値を表示するかは、リスト系のコンポーネントの場合はlabelFieldプロパティ使って指定する。
(注)XMLのノードの属性の値を表示する場合は、指定する値の先頭に「@」をつける必要があるので注意。
- データグリッド(mx.controls.DataGrid?)は複数列に渡ってデータを表示するので、以下のようにリスト系のコンポーネントとは使い方が異なる点がある。
- 各カラムの情報を設定するために、columnsプロパティにmx.controls.dataGridClasses?.DataGridColumn?クラスの配列を指定する必要がある。
- DataGridColumn?ではheaderTextプロパティにヘッダ行に表示するテキスト、dataFieldプロパティ(labelFieldではないので要注意)にどのフィールドの値を表示するかを指定する。
dataFieldプロパティに指定した値は、表示だけでなくソートのキーとしても使用される。 (後述のレンダラーやラベルファンクションを指定する場合にも効いてくるので重要)
- columsプロパティの指定は、下記の例のようにタグで記述すると簡単に行える。
<mx:DataGrid>
<mx:columns>
<mx:DataGridColumn headerText="ヘッダ行に表示するテキスト1" dataField="対象フィールド1" />
<mx:DataGridColumn headerText="ヘッダ行に表示するテキスト2" dataField="対象フィールド2" />
<mx:DataGridColumn headerText="ヘッダ行に表示するテキスト3" dataField="対象フィールド3" />
</mx:columns>
</mx:DataGrid>
- XMLと連携する
- XMLデータをFlexで読み込むには色々な方法があるが、最も手っ取り早くて確実なのが<mx:XML>タグを使う方法である。
- プロジェクト内のXMLファイルを<mx:XML>タグを使って読み込む場合は、sourceプロパティにMXMLファイルの位置からの相対パスで指定する。
この場合、対象のXMLファイルはコンパイル時にswfファイルに組み込まれ、初期化時にはXMLのパースまで終了した状態になっているので、読み込み完了まで待つという処理を行う必要がない。
さらに、コンパイル時にXMLファイルの存在チェックや、正しい形式のXMLかどうかのチェックまで行ってくれるので、他の方法に比べて非常におすすめ。
- XMLをデータプロバイダに指定する場合は、コンポーネントのdataProviderプロパティに対象のXMLオブジェクトの繰り返し部分のノードを指定する。
(注)このとき、ルートノードの要素はデータプロバイダの記述に含めないので要注意。
- labelFieldプロパティやdataFieldプロパティに指定する値は、dataProviderプロパティに指定したノードからの相対パスで指定する。
- (注)データプロバイダにXMLを指定する場合は、各要素の値はデータバインディング可能にできないので注意。
(デバッグ実行時に警告が大量に発生する)
- サンプルプログラムで使用する対象のXMLデータ -
xml/data.xml
<?xml version="1.0" encoding="utf-8"?>
<root>
<person>
<lastName>山田</lastName>
<firstName>太郎</firstName>
<age>21</age>
<tel>000-111-222</tel>
<email>aaa@hoge.com</email>
<gender>男</gender>
</person>
<person>
<lastName>佐藤</lastName>
<firstName>花子</firstName>
<age>25</age>
<tel>111-222-333</tel>
<email>bbb@hoge.com</email>
<gender>女</gender>
</person>
<person>
<lastName>スミス</lastName>
<firstName>ジョン</firstName>
<age>41</age>
<tel>999-111-222</tel>
<email>ccc@hoge.com</email>
<gender>男</gender>
</person>
<person>
<lastName>斉藤</lastName>
<firstName>次郎</firstName>
<age>22</age>
<tel>555-111-222</tel>
<email>ddd@hoge.com</email>
<gender>男</gender>
</person>
<person>
<lastName>鈴木</lastName>
<firstName>さくら</firstName>
<age>15</age>
<tel>666-111-222</tel>
<email>eee@hoge.com</email>
<gender>女</gender>
</person>
</root>
- サンプルプログラム - リストのデータプロバイダにXMLのデータを指定 (実行画面はこちら)
ListXMLDataProviderSample.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:XML id="xmlData" source="xml/data.xml" />
<mx:VBox width="100%" height="100%">
<mx:List
dataProvider="{this.xmlData.person}"
labelField="lastName"
/>
</mx:VBox>
</mx:Application>
- サンプルプログラム - データグリッドのデータプロバイダにXMLのデータを指定 (実行画面はこちら)
DataGridXMLDataProviderSample.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:XML id="xmlData" source="xml/data.xml" />
<mx:VBox width="100%" height="100%">
<mx:DataGrid dataProvider="{this.xmlData.person}">
<mx:columns>
<mx:DataGridColumn headerText="姓" dataField="lastName" />
<mx:DataGridColumn headerText="名" dataField="firstName" />
<mx:DataGridColumn headerText="年齢" dataField="age" />
<mx:DataGridColumn headerText="電話番号" dataField="tel" />
<mx:DataGridColumn headerText="メールアドレス" dataField="email" />
<mx:DataGridColumn headerText="性別" dataField="gender" />
</mx:columns>
</mx:DataGrid>
</mx:VBox>
</mx:Application>
- Arrayと連携する
- 配列(Array)データをデータプロバイダに指定する場合は、配列に格納するオブジェクトは生のObjectクラス(無名オブジェクト)を使う方法と、DTOクラスを使う方法がある。
- 無名オブジェクトを使う方法の場合は、あらかじめクラスを定義しなくても自由なプロパティを持つオブジェクトを手っ取り早く作ることができる。
ただし、XMLの場合と同じく各要素の値はデータバインディング可能にできないので注意。
(デバッグ実行時に警告が大量に発生する)
- DTOクラスを使う方法の場合は、あらかじめDTOクラスを定義する必要があるので他の方法に比べて手間がかかる。
しかし、DTOクラスは読み取り専用のGetterプロパティを定義したり、サーバー側との連携に使ったりすることもできるなど、色々とメリットがあるので最もおすすめの方法である。
- サンプルプログラム - リストのデータプロバイダに配列のデータを指定 (実行画面はこちら)
ListArrayDataProviderSample.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Script>
<![CDATA[
[Bindable]
private var dataArray :Array =
[
{
lastName: "山田",
firstName: "太郎",
age: 21,
tel: "000-111-222",
email: "aaa@hoge.com",
gender: "男"
},
{
lastName: "佐藤",
firstName: "花子",
age: 25,
tel: "111-222-333",
email: "bbb@hoge.com",
gender: "女"
},
{
lastName: "スミス",
firstName: "ジョン",
age: 41,
tel: "999-111-222",
email: "ccc@hoge.com",
gender: "男"
},
{
lastName: "斉藤",
firstName: "次郎",
age: 22,
tel: "555-111-222",
email: "ddd@hoge.com",
gender: "男"
},
{
lastName: "鈴木",
firstName: "さくら",
age: 15,
tel: "666-111-222",
email: "eee@hoge.com",
gender: "女"
}
];
]]>
</mx:Script>
<mx:VBox width="100%" height="100%">
<mx:List
dataProvider="{this.dataArray}"
labelField="lastName"
/>
</mx:VBox>
</mx:Application>
- サンプルプログラム - データグリッドのデータプロバイダに配列のデータを指定 (実行画面はこちら)
DataGridArrayDataProviderSample.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Script>
<![CDATA[
[Bindable]
private var dataArray :Array =
[
{
lastName: "山田",
firstName: "太郎",
age: 21,
tel: "000-111-222",
email: "aaa@hoge.com",
gender: "男"
},
{
lastName: "佐藤",
firstName: "花子",
age: 25,
tel: "111-222-333",
email: "bbb@hoge.com",
gender: "女"
},
{
lastName: "スミス",
firstName: "ジョン",
age: 41,
tel: "999-111-222",
email: "ccc@hoge.com",
gender: "男"
},
{
lastName: "斉藤",
firstName: "次郎",
age: 22,
tel: "555-111-222",
email: "ddd@hoge.com",
gender: "男"
},
{
lastName: "鈴木",
firstName: "さくら",
age: 15,
tel: "666-111-222",
email: "eee@hoge.com",
gender: "女"
}
];
]]>
</mx:Script>
<mx:VBox width="100%" height="100%">
<mx:DataGrid dataProvider="{this.dataArray}">
<mx:columns>
<mx:DataGridColumn headerText="姓" dataField="lastName" />
<mx:DataGridColumn headerText="名" dataField="firstName" />
<mx:DataGridColumn headerText="年齢" dataField="age" />
<mx:DataGridColumn headerText="電話番号" dataField="tel" />
<mx:DataGridColumn headerText="メールアドレス" dataField="email" />
<mx:DataGridColumn headerText="性別" dataField="gender" />
</mx:columns>
</mx:DataGrid>
</mx:VBox>
</mx:Application>
- サンプルプログラム - データグリッドのデータプロバイダにDTOの配列のデータを指定 (実行画面はこちら)
DataGridArrayDtoDataProviderSample.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
creationComplete="onCreationComplete()"
>
<mx:Script>
<![CDATA[
import dto.PersonDto;
[Bindable]
private var dataArray :Array = new Array();
private function onCreationComplete() :void
{
this.dataArray.push(new PersonDto("山田", "太郎", 21, "000-111-222", "aaa@hoge.com", "男"));
this.dataArray.push(new PersonDto("佐藤", "花子", 25, "111-222-333", "bbb@hoge.com", "女"));
this.dataArray.push(new PersonDto("スミス", "ジョン", 41, "999-111-222", "ccc@hoge.com", "男"));
this.dataArray.push(new PersonDto("斉藤", "次郎", 22, "555-111-222", "ddd@hoge.com", "男"));
this.dataArray.push(new PersonDto("鈴木", "さくら", 15, "666-111-222", "eee@hoge.com", "女"));
this.arrayDataGrid.dataProvider = this.dataArray;
}
]]>
</mx:Script>
<mx:VBox width="100%" height="100%">
<mx:DataGrid id="arrayDataGrid">
<mx:columns>
<mx:DataGridColumn headerText="姓" dataField="lastName" />
<mx:DataGridColumn headerText="名" dataField="firstName" />
<mx:DataGridColumn headerText="年齢" dataField="age" />
<mx:DataGridColumn headerText="電話番号" dataField="tel" />
<mx:DataGridColumn headerText="メールアドレス" dataField="email" />
<mx:DataGridColumn headerText="性別" dataField="gender" />
</mx:columns>
</mx:DataGrid>
</mx:VBox>
</mx:Application>
dto.PersonDto.as
package dto
{
[Bindable]
public class PersonDto
{
public var lastName :String = null;
public var firstName :String = null;
public var age :int = 0;
public var tel :String = null;
public var email :String = null;
public var gender :String = null;
@param @param @param @param @param @param
public function PersonDto(lastName :String = null, firstName :String = null, age :int = 0, tel :String = null, email :String = null, gender :String = null)
{
this.lastName = lastName;
this.firstName = firstName;
this.age = age;
this.tel = tel;
this.email = email;
this.gender = gender;
}
}
}
- ArrayとArrayCollection?の違い
- 単純な配列(Arrayクラス)をデータプロバイダに指定した場合は、配列に要素を追加・削除しても変更が反映されない。
これに対して、Arrayクラスをラッピングしたmx.collections.ArrayCollection?クラスをデータプロバイダに指定した場合は、配列に要素を追加・削除した場合も変更が反映される。
- ArrayCollection?に配列を関連付けるには、コンストラクタで指定するか、ArrayCollection?のsourceプロパティに配列を指定する。
- ArrayCollection?への要素の追加はaddItem()メソッド、要素の削除はremoveItemAt?()メソッドを使って行う。
(注)中身の配列へ直接要素の追加・削除を行ってもよいが、その場合はArrayCollection?のrefresh()メソッドを呼ばないと変更が反映されないので注意。
- ArrayのラッピングクラスにArrayCollection?クラスがあるように、XMLの場合はmx.collections.XMLListCollection?というラッピングクラスがある。
- データプロバイダにArrayやXMLを指定した場合は、実際には裏でArrayCollection?やXMLListCollection?のインスタンスが生成されて、そちらがデータプロバイダに割り当てられる。
- サンプルプログラム - データグリッドのデータプロバイダにArrayとArrayCollection?を指定した場合の動作の違い (実行画面はこちら)
DataGridArrayCollectionDataProviderSample.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
creationComplete="onCreationComplete()"
>
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import dto.PersonDto;
[Bindable]
private var dataArray :Array = new Array();
[Bindable]
private var dataArrayCollection :ArrayCollection = new ArrayCollection();
private function onCreationComplete() :void
{
this.dataArray.push(new PersonDto("山田", "太郎", 21, "000-111-222", "aaa@hoge.com", "男"));
this.dataArray.push(new PersonDto("佐藤", "花子", 25, "111-222-333", "bbb@hoge.com", "女"));
this.dataArrayCollection.source = this.dataArray;
}
private function onAddArrayButtonClick() :void
{
this.dataArray.push(new PersonDto("Arrayに", "追加", 88, "888-111-222", "array@hoge.com", "男"));
}
private function onAddArrayWithRefreshButtonClick() :void
{
this.dataArray.push(new PersonDto("Arrayに", "追加(Refresh付き)", 89, "889-111-222", "arrayRefresh@hoge.com", "男"));
this.dataArrayCollection.refresh();
}
private function onAddArrayCollectionButtonClick() :void
{
this.dataArrayCollection.addItem(new PersonDto("ArrayCollectionに", "追加", 99, "999-111-222", "arrayCollection@hoge.com", "男"));
}
private function onDataProviderResetButtonClick() :void
{
this.arrayDataGrid.dataProvider = this.dataArray;
this.arrayCollectionDataGrid.dataProvider = this.dataArrayCollection;
}
]]>
</mx:Script>
<mx:VBox width="100%" height="100%">
<mx:Panel width="100%" height="100%" title="Arrayをデータプロバイダに設定">
<mx:DataGrid id="arrayDataGrid" dataProvider="{this.dataArray}" width="100%" height="100%">
<mx:columns>
<mx:DataGridColumn headerText="姓" dataField="lastName" />
<mx:DataGridColumn headerText="名" dataField="firstName" />
<mx:DataGridColumn headerText="年齢" dataField="age" />
<mx:DataGridColumn headerText="電話番号" dataField="tel" />
<mx:DataGridColumn headerText="メールアドレス" dataField="email" />
<mx:DataGridColumn headerText="性別" dataField="gender" />
</mx:columns>
</mx:DataGrid>
</mx:Panel>
<mx:Panel width="100%" height="100%" title="ArrayCollectionをデータプロバイダに設定">
<mx:DataGrid id="arrayCollectionDataGrid" dataProvider="{this.dataArrayCollection}" width="100%" height="100%">
<mx:columns>
<mx:DataGridColumn headerText="姓" dataField="lastName" />
<mx:DataGridColumn headerText="名" dataField="firstName" />
<mx:DataGridColumn headerText="年齢" dataField="age" />
<mx:DataGridColumn headerText="電話番号" dataField="tel" />
<mx:DataGridColumn headerText="メールアドレス" dataField="email" />
<mx:DataGridColumn headerText="性別" dataField="gender" />
</mx:columns>
</mx:DataGrid>
</mx:Panel>
<mx:Button label="Arrayにデータ追加" click="onAddArrayButtonClick()" />
<mx:Button label="Arrayにデータ追加(Refresh付き)" click="onAddArrayWithRefreshButtonClick()" />
<mx:Button label="ArrayCollectionにデータ追加" click="onAddArrayCollectionButtonClick()" />
<mx:Button label="dataProviderをリセット" click="onDataProviderResetButtonClick()" />
</mx:VBox>
</mx:Application>
- ソート順の指定
- データグリッドのソート順は、実はデータグリッドコントロールではなく、データプロバイダに指定したデータ側に設定されている。
(XMLでデータを指定した場合はXMLListCollection?, 配列でデータを指定した場合はArrayCollection?)
- XMLListCollection?やArrayCollection?のsortプロパティを使えば、スクリプトでソート順の取得・変更を行うことができる。
- ソート順は、mx.collections.Sortクラスとその要素クラスであるmx.collections.SortField?クラスによって表現される。
- スクリプトでsortプロパティの値を変更した場合は、必ずrefresh()メソッドを呼び出して変更を反映させる必要がある。
- サンプルプログラム - データグリッドのソート順をスクリプトで変更 (実行画面はこちら)
DataGridSortSample.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
creationComplete="onCreationComplete()"
>
<mx:Script>
<![CDATA[
import mx.collections.SortField;
import mx.collections.Sort;
import mx.collections.ArrayCollection;
import dto.PersonDto;
[Bindable]
private var dataArray :Array = new Array();
[Bindable]
private var dataArrayCollection :ArrayCollection = new ArrayCollection();
private function onCreationComplete() :void
{
this.dataArray.push(new PersonDto("山田", "太郎", 21, "000-111-222", "aaa@hoge.com", "男"));
this.dataArray.push(new PersonDto("佐藤", "花子", 25, "111-222-333", "bbb@hoge.com", "女"));
this.dataArray.push(new PersonDto("スミス", "ジョン", 41, "999-111-222", "ccc@hoge.com", "男"));
this.dataArray.push(new PersonDto("斉藤", "次郎", 22, "555-111-222", "ddd@hoge.com", "男"));
this.dataArray.push(new PersonDto("鈴木", "さくら", 15, "666-111-222", "eee@hoge.com", "女"));
this.dataArrayCollection.source = this.dataArray;
var sort :Sort = new Sort();
sort.fields = [new SortField("tel")];
this.dataArrayCollection.sort = sort;
this.dataArrayCollection.refresh();
}
private function onLastNameSortButtonClick() :void
{
var sort :Sort = new Sort();
sort.fields = [new SortField("lastName", false, true, false)];
this.dataArrayCollection.sort = sort;
this.dataArrayCollection.refresh();
}
private function onMultiSortButtonClick() :void
{
var sort :Sort = new Sort();
sort.fields = [new SortField("gender"), new SortField("email")];
this.dataArrayCollection.sort = sort;
this.dataArrayCollection.refresh();
}
]]>
</mx:Script>
<mx:VBox width="100%" height="100%">
<mx:DataGrid id="arrayCollectionDataGrid" dataProvider="{this.dataArrayCollection}">
<mx:columns>
<mx:DataGridColumn headerText="姓" dataField="lastName" />
<mx:DataGridColumn headerText="名" dataField="firstName" />
<mx:DataGridColumn headerText="年齢" dataField="age" />
<mx:DataGridColumn headerText="電話番号" dataField="tel" />
<mx:DataGridColumn headerText="メールアドレス" dataField="email" />
<mx:DataGridColumn headerText="性別" dataField="gender" />
</mx:columns>
</mx:DataGrid>
<mx:Button label="姓の降順でソート" click="onLastNameSortButtonClick()" />
<mx:Button label="複数カラムでソート" click="onMultiSortButtonClick()" />
</mx:VBox>
</mx:Application>
- ツリーの表示
- ツリーに表示するデータを設定する場合も、リストと同じようにデータプロバイダで行う。
- ツリー構造のXMLをdataProviderに指定する方法が一般的で、世間に出回っているサンプルにもほとんどその方法しか載っていないが、DTOの配列を指定する方法もある。
(むしろ、そちらの方が応用範囲が広がるのでおすすめ)
- DTOの配列を指定する場合は、「children」という名前のArray型(ArrayCollection?でも可)のプロパティに配下の要素を格納する必要がある。
(注)「children」以外の名前だと配下の要素と認識されないので注意。
- サーバー側のオブジェクトのマッピングの都合などで配下の要素のプロパティ名を「children」にできない場合は、下記の例のように読み取り専用プロパティとして「children」を用意して、他のArray型のフィールドの値をそのまま返すという荒技で対処することができる。
public var subElementArray :Array;
public function get children() :Array
{
return this.subElementArray;
}
- XMLで指定する場合は、配下の要素を持つ場合のみブランチノードと見なされるので、中身のないブランチノードを作ることはできない。
- DTOの配列で指定する場合は、childrenプロパティがnullのオブジェクトがリーフノード、それ以外のオブジェクトがブランチノードと見なされるので、childrenプロパティに空配列を指定すれば中身のないブランチノードを作ることもできる。
- サンプルプログラム - ツリーのデータプロバイダにXMLのデータを指定 (実行画面はこちら)
TreeXMLDataProviderSample.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:XML id="xmlData" source="xml/treeData.xml" />
<mx:VBox width="100%" height="100%">
<mx:Tree width="100%" height="100%"
dataProvider="{this.xmlData.node}"
labelField="@name"
/>
</mx:VBox>
</mx:Application>
対象のXMLデータ - xml/treeData.xml
<?xml version="1.0" encoding="utf-8"?>
<root>
<node name="1">
<node name="1-1" />
<node name="1-2">
<node name="1-2-1" />
<node name="1-2-2" />
</node>
<node name="1-3" />
</node>
<node name="2" />
<node name="3">
<node name="3-1" />
<node name="3-2" />
</node>
</root>
- サンプルプログラム - ツリーのデータプロバイダにDTOの配列のデータを指定 (実行画面はこちら)
TreeDtoArrayDataProviderSample.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
creationComplete="onCreationComplete()"
>
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import dto.TreeDataDto;
[Bindable]
private var dataArray :Array = new Array();
[Bindable]
private var dataArrayCollection :ArrayCollection = new ArrayCollection();
private function onCreationComplete() :void
{
var node1 :TreeDataDto =
new TreeDataDto("1",
[
new TreeDataDto("1-1"),
new TreeDataDto("1-2",
[
new TreeDataDto("1-2-1"),
new TreeDataDto("1-2-2")
]),
new TreeDataDto("1-3(childrenに空配列を指定)", new Array())
]
);
var node2 :TreeDataDto = new TreeDataDto("2");
var node3 :TreeDataDto =
new TreeDataDto("3",
[
new TreeDataDto("3-1"),
new TreeDataDto("3-2")
]
);
this.dataArray = [node1, node2, node3];
this.dataArrayCollection.source = this.dataArray;
}
]]>
</mx:Script>
<mx:VBox width="100%" height="100%">
<mx:Tree width="100%" height="100%"
dataProvider="{this.dataArrayCollection}"
labelField="name"
/>
</mx:VBox>
</mx:Application>
dto.TreeDataDto.as
package dto
{
[Bindable]
public class TreeDataDto
{
public var name :String = null;
public var children :Array = null;
@param @param
public function TreeDataDto(name :String = null, children :Array = null)
{
this.name = name;
this.children = children;
}
}
}
レンダラーとラベルファンクション (P287 ~ P290) †
- レンダラーとラベルファンクションの基礎知識
- レンダラーとラベルファンクションは共に表示方法をカスタマイズするための仕組み。
- ラベルファンクションは、表示される文字列のみをカスタマイズすることができる。
できることは限られているが、シンプルゆえに使いやすい。
- レンダラーは、文字列の代わりに任意のコンポーネントを表示することができる。
これを使えば、データグリッドの列の中に画像やチェックボックスを表示することもできる。
簡単なレンダラーを作成するのはそれほど難しくないが、高度にカスタマイズされたレンダラーを作成するにはかなりの知識を必要とするので奥が深い。
- レンダラーとラベルファンクションの使い分けは以下のように行うと良い。
- 単純なフォーマット変換 (カンマ区切りで表示、日付フォーマット変換など) → ラベルファンクション
- 複数のデータを1列にまとめて表示したい → レンダラー
- 表示をラベルではなくリンクにしたい → レンダラー
- 列の中にボタンやチェックボックスを表示したい → レンダラー
- ラベルファンクション
- リスト系コントロール用のラベルファンクション
- コントロールのlabelFunctionプロパティに、フォーマット変換を行うメソッドのFunctionオブジェクトを指定する。
(注)Functionオブジェクトを指定する場合は、メソッド名の後ろに「()」をつけてはいけないので注意。
- 指定できるメソッドの形式は下記の形式と決まっている。
(注)引数の数・型が合わないメソッドをラベルファンクションに指定した場合は、コンパイル時ではなく実行時にエラーになるので注意。
@param @return
private function myListLabelFunction(item :Object) :String {}
- labelFieldで指定したフィールドの値は表示されず、labelFunctionに指定した関数からの戻り値が実際に表示される文字列となる。
- サンプルプログラム - リストにラベルファンクションを指定 (実行画面はこちら)
ListLabelFunctionSample.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
creationComplete="onCreationComplete()"
>
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import dto.PersonDto;
[Bindable]
private var dataArray :Array = new Array();
[Bindable]
private var dataArrayCollection :ArrayCollection = new ArrayCollection();
private function onCreationComplete() :void
{
this.dataArray.push(new PersonDto("山田", "太郎", 21, "000-111-222", "aaa@hoge.com", "男"));
this.dataArray.push(new PersonDto("佐藤", "花子", 25, "111-222-333", "bbb@hoge.com", "女"));
this.dataArray.push(new PersonDto("スミス", "ジョン", 41, "999-111-222", "ccc@hoge.com", "男"));
this.dataArray.push(new PersonDto("斉藤", "次郎", 22, "555-111-222", "ddd@hoge.com", "男"));
this.dataArray.push(new PersonDto("鈴木", "さくら", 15, "666-111-222", "eee@hoge.com", "女"));
this.dataArrayCollection.source = this.dataArray;
}
@param @return
private function formatAge(item :Object) :String
{
var person :PersonDto = item as PersonDto;
return person.age + "歳";
}
]]>
</mx:Script>
<mx:VBox width="100%" height="100%">
<mx:List
dataProvider="{this.dataArrayCollection}"
labelFunction="formatAge"
/>
</mx:VBox>
</mx:Application>
- データグリッド用のラベルファンクション
- 指定できるメソッドの形式は下記の形式と決まっている。
(注)データグリッド用のラベルファンクションは、リスト系コントロール用のものとはメソッドの引数の形式が違うので要注意。
@param @param @return
private function myDataGridLabelFunction(item :Object, column :DataGridColumn) :String {}
- dataFieldに指定したフィールドの値は、下記の例のようにすると取得できる。
var targetObj :Object = item[column.dataField];
var targetStr :String = item[column.dataField];
- サンプルプログラム - データグリッドにラベルファンクションを指定 (実行画面はこちら)
DataGridLabelFunctionSample.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
creationComplete="onCreationComplete()"
>
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import dto.PersonDto;
[Bindable]
private var dataArray :Array = new Array();
[Bindable]
private var dataArrayCollection :ArrayCollection = new ArrayCollection();
private function onCreationComplete() :void
{
this.dataArray.push(new PersonDto("山田", "太郎", 21, "000-111-222", "aaa@hoge.com", "男"));
this.dataArray.push(new PersonDto("佐藤", "花子", 25, "111-222-333", "bbb@hoge.com", "女"));
this.dataArray.push(new PersonDto("スミス", "ジョン", 41, "999-111-222", "ccc@hoge.com", "男"));
this.dataArray.push(new PersonDto("斉藤", "次郎", 22, "555-111-222", "ddd@hoge.com", "男"));
this.dataArray.push(new PersonDto("鈴木", "さくら", 15, "666-111-222", "eee@hoge.com", "女"));
this.dataArrayCollection.source = this.dataArray;
}
@param @param @return
private function formatAge(item :Object, column :DataGridColumn) :String
{
var targetStr :String = item[column.dataField];
return targetStr + "歳";
}
]]>
</mx:Script>
<mx:VBox width="100%" height="100%">
<mx:DataGrid id="arrayCollectionDataGrid" dataProvider="{this.dataArrayCollection}" width="100%">
<mx:columns>
<mx:DataGridColumn headerText="姓" dataField="lastName" />
<mx:DataGridColumn headerText="名" dataField="firstName" />
<mx:DataGridColumn headerText="年齢" dataField="age" labelFunction="formatAge" />
<mx:DataGridColumn headerText="電話番号" dataField="tel" />
<mx:DataGridColumn headerText="メールアドレス" dataField="email" />
<mx:DataGridColumn headerText="性別" dataField="gender" />
</mx:columns>
</mx:DataGrid>
</mx:VBox>
</mx:Application>
- 指定するのはあくまでもFunctionオブジェクト
- ラベルファンクションに指定するのはあくまでも単なるFunctionオブジェクトなので、同じクラス内のメソッドでなくても指定できる。
- そこで、数値をカンマ区切りに変換したり、日付フォーマットを行ったり汎用的なフォーマッタはユーティリティクラスにstaticなメソッドとして定義しておくと、どの画面からも共通のラベルファンクションとして使用できるので便利である。
- ユーティリティクラスにラベルファンクションを定義する場合は、リスト系コントロール用のものと、データグリッド用のものを両方定義しておくと良い。
- ラベルファンクションでは渡されたデータと全然関係のない文字列を返しても良いが、あまり意味がないのでおそらくそんなことをすることはない(はず)。
- DTOの読み取り専用プロパティで代用
- データプロバイダにDTOの配列を使用する場合は、ラベルファンクションを用意する代わりに、DTO側にフォーマット用の読み取り専用プロパティを用意してその値を表示することもできる。
- もちろん、ラベルファンクションと併用して使用することもできる。
- この方法は、リスト系のコンポーネントとデータグリッドのラベルファンクションのメソッドの形式の違いに影響されないのでおすすめ。
- サンプルプログラム - ラベルファンクションの代わりにDTOの読み取り専用プロパティを使って表示文字列をカスタマイズ (実行画面はこちら)
DataGridDtoGetterSample.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
creationComplete="onCreationComplete()"
>
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import dto.PersonMk2Dto;
[Bindable]
private var dataArray :Array = new Array();
[Bindable]
private var dataArrayCollection :ArrayCollection = new ArrayCollection();
private function onCreationComplete() :void
{
this.dataArray.push(new PersonMk2Dto("山田", "太郎", 21, "000-111-222", "aaa@hoge.com", "男"));
this.dataArray.push(new PersonMk2Dto("佐藤", "花子", 25, "111-222-333", "bbb@hoge.com", "女"));
this.dataArray.push(new PersonMk2Dto("スミス", "ジョン", 41, "999-111-222", "ccc@hoge.com", "男"));
this.dataArray.push(new PersonMk2Dto("斉藤", "次郎", 22, "555-111-222", "ddd@hoge.com", "男"));
this.dataArray.push(new PersonMk2Dto("鈴木", "さくら", 15, "666-111-222", "eee@hoge.com", "女"));
this.dataArrayCollection.source = this.dataArray;
}
@param @param @return
private function formatAge(item :Object, column :DataGridColumn) :String
{
var targetStr :String = item[column.dataField];
return targetStr + "歳";
}
]]>
</mx:Script>
<mx:VBox width="100%" height="100%">
<mx:DataGrid id="arrayCollectionDataGrid" dataProvider="{this.dataArrayCollection}" width="100%">
<mx:columns>
<mx:DataGridColumn headerText="姓" dataField="lastName" />
<mx:DataGridColumn headerText="名" dataField="firstName" />
<mx:DataGridColumn headerText="フルネーム" dataField="fullName" />
<mx:DataGridColumn headerText="年齢(ラベルファンクション)" dataField="age" labelFunction="formatAge" />
<mx:DataGridColumn headerText="年齢(Getter)" dataField="formattedAge" />
<mx:DataGridColumn headerText="電話番号" dataField="tel" />
<mx:DataGridColumn headerText="メールアドレス" dataField="email" />
<mx:DataGridColumn headerText="性別" dataField="gender" />
<mx:DataGridColumn headerText="性別マーク" dataField="genderMark" />
</mx:columns>
</mx:DataGrid>
</mx:VBox>
</mx:Application>
dto.PersonMk2Dto.as
package dto
{
[Bindable]
public class PersonMk2Dto
{
public var lastName :String = null;
public var firstName :String = null;
public var age :int = 0;
public var tel :String = null;
public var email :String = null;
public var gender :String = null;
@param @param @param @param @param @param
public function PersonMk2Dto(lastName :String = null, firstName :String = null, age :int = 0, tel :String = null, email :String = null, gender :String = null)
{
this.lastName = lastName;
this.firstName = firstName;
this.age = age;
this.tel = tel;
this.email = email;
this.gender = gender;
}
@return
public function get fullName() :String
{
return this.lastName + " " + this.firstName;
}
@return
public function get formattedAge() :String
{
return this.age + "才";
}
@return
public function get genderMark() :String
{
if(this.gender == "男")
{
return "♂"
}
else
{
return "♀";
}
}
}
}
- レンダラー
- 既存のコントロールをレンダラーに指定
- コントロールのitemRendererプロパティに表示したいコントロールのクラス名を、「mx.controls.Image」のようにパッケージも含めた完全クラス名で指定すると、文字列の代わりに指定したコントロールが表示される。
- データグリッドの場合は、データグリッド本体ではなくDataGridColumn?のitemRendererプロパティに指定する。
- サンプルプログラム - レンダラーにImageコントロールを指定 (実行画面はこちら)
DataGridImageRendererSample.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
creationComplete="onCreationComplete()"
>
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import dto.PersonDto;
[Bindable]
private var dataArray :Array =
[
{
name :"AX-2000-R",
color :"レッド",
image :"http://www.sharp.co.jp/products/kitchen/w_oven/prod01/ax2000r/images/ax2000r===04.jpg"
},
{
name :"AX-2000-B",
color :"ブラック",
image :"http://www.sharp.co.jp/products/kitchen/w_oven/prod01/ax2000b/images/ax2000b===04.jpg"
},
{
name :"AX-HC4-R",
color :"レッド",
image :"http://www.sharp.co.jp/products/kitchen/w_oven/prod01/axhc4r/images/axhc4r===04.jpg"
},
{
name :"AX-HC4-S",
color :"シルバー",
image :"http://www.sharp.co.jp/products/kitchen/w_oven/prod01/axhc4s/images/axhc4s===04.jpg"
},
{
name :"AX-HT4-C",
color :"ベージュ",
image :"http://www.sharp.co.jp/products/kitchen/w_oven/prod01/axht4c/images/axht4c===04.jpg"
},
];
[Bindable]
private var dataArrayCollection :ArrayCollection = new ArrayCollection();
private function onCreationComplete() :void
{
this.dataArrayCollection.source = this.dataArray;
}
]]>
</mx:Script>
<mx:VBox width="100%" height="100%">
<mx:DataGrid id="arrayCollectionDataGrid" dataProvider="{this.dataArrayCollection}" width="100%" height="100%" rowHeight="150">
<mx:columns>
<mx:DataGridColumn headerText="形名" dataField="name" />
<mx:DataGridColumn headerText="色" dataField="color" />
<mx:DataGridColumn headerText="画像" dataField="image" itemRenderer="mx.controls.Image" />
</mx:columns>
</mx:DataGrid>
</mx:VBox>
</mx:Application>
- インラインでレンダラーを記述
- コントロールのitemRendererプロパティを記述する代わりに、下記の例のように<mx:itemRenderer>というタグを入れ子で記述すると、自由なコンポーネントを表示できる。
(注)このとき、なぜか<mx:Component>というタグをワンクッション挟む必要があるので注意。
<mx:List>
<mx:itemRenderer>
<mx:Component>
</mx:Component>
</mx:itemRenderer>
</mxList>
<mx:DataGrid>
<mx:columns>
<mx:DataGridColumn>
<mx:itemRenderer>
<mx:Component>
</mx:Component>
</mx:itemRenderer>
</mx:DataGridColumn>
</mx:columns>
</mx:DataGrid>
- 単純なコントロールだけでなく、コンテナも表示できるのでかなり自由度が高い。
- レンダラーの中で現在処理対象となっているデータには「data」でアクセスできる。
- サンプルプログラム - インラインでレンダラーを記述 (実行画面はこちら)
DataGridInlineRendererSample.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
creationComplete="onCreationComplete()"
>
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import dto.PersonDto;
[Bindable]
private var dataArray :Array = new Array();
[Bindable]
private var dataArrayCollection :ArrayCollection = new ArrayCollection();
private function onCreationComplete() :void
{
this.dataArray.push(new PersonDto("山田", "太郎", 21, "000-111-222", "aaa@hoge.com", "男"));
this.dataArray.push(new PersonDto("佐藤", "花子", 25, "111-222-333", "bbb@hoge.com", "女"));
this.dataArray.push(new PersonDto("スミス", "ジョン", 41, "999-111-222", "ccc@hoge.com", "男"));
this.dataArray.push(new PersonDto("斉藤", "次郎", 22, "555-111-222", "ddd@hoge.com", "男"));
this.dataArray.push(new PersonDto("鈴木", "さくら", 15, "666-111-222", "eee@hoge.com", "女"));
this.dataArrayCollection.source = this.dataArray;
}
]]>
</mx:Script>
<mx:VBox width="100%" height="100%">
<mx:DataGrid id="arrayCollectionDataGrid" dataProvider="{this.dataArrayCollection}" width="100%" rowHeight="80">
<mx:columns>
<mx:DataGridColumn headerText="姓" dataField="lastName" />
<mx:DataGridColumn headerText="名" dataField="firstName" />
<mx:DataGridColumn headerText="年齢" dataField="age" />
<mx:DataGridColumn headerText="その他もろもろ">
<mx:itemRenderer>
<mx:Component>
<mx:VBox>
<mx:Label text="電話番号: {data.tel}" />
<mx:Label text="メールアドレス: {data.email}" />
<mx:CheckBox label="男性" selected="{data.gender == '男'}" />
</mx:VBox>
</mx:Component>
</mx:itemRenderer>
</mx:DataGridColumn>
</mx:columns>
</mx:DataGrid>
</mx:VBox>
</mx:Application>
- MXMLでレンダラークラスを作成
- 独自にMXMLファイルで作成したクラスも、既存のコントロールと同じようにitemRendererプロパティにパッケージも含めた完全クラス名で指定することにより表示できる。
- インラインで記述するレンダラーをそのまま独立したMXMLファイルに分離するような感じなので、記述する内容はインラインの場合とほとんど変わらない。
- サンプルプログラム - MXMLで作成したレンダラーを指定 (実行画面はこちら)
MXMLで作成したレンダラー - renderer.MXMLRenderer.mxml
<?xml version="1.0"?>
<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Label text="電話番号: {data.tel}" />
<mx:Label text="メールアドレス: {data.email}" />
<mx:CheckBox label="男性" selected="{data.gender == '男'}" />
</mx:VBox>
レンダラーを使用する側 - DataGridMXMLRendererSample.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
creationComplete="onCreationComplete()"
>
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import dto.PersonDto;
[Bindable]
private var dataArray :Array = new Array();
[Bindable]
private var dataArrayCollection :ArrayCollection = new ArrayCollection();
private function onCreationComplete() :void
{
this.dataArray.push(new PersonDto("山田", "太郎", 21, "000-111-222", "aaa@hoge.com", "男"));
this.dataArray.push(new PersonDto("佐藤", "花子", 25, "111-222-333", "bbb@hoge.com", "女"));
this.dataArray.push(new PersonDto("スミス", "ジョン", 41, "999-111-222", "ccc@hoge.com", "男"));
this.dataArray.push(new PersonDto("斉藤", "次郎", 22, "555-111-222", "ddd@hoge.com", "男"));
this.dataArray.push(new PersonDto("鈴木", "さくら", 15, "666-111-222", "eee@hoge.com", "女"));
this.dataArrayCollection.source = this.dataArray;
}
]]>
</mx:Script>
<mx:VBox width="100%" height="100%">
<mx:DataGrid id="arrayCollectionDataGrid" dataProvider="{this.dataArrayCollection}" width="100%" rowHeight="80">
<mx:columns>
<mx:DataGridColumn headerText="姓" dataField="lastName" />
<mx:DataGridColumn headerText="名" dataField="firstName" />
<mx:DataGridColumn headerText="年齢" dataField="age" />
<mx:DataGridColumn headerText="その他もろもろ" itemRenderer="renderer.MXMLRenderer" />
</mx:columns>
</mx:DataGrid>
</mx:VBox>
</mx:Application>
- ActionScript?でレンダラークラスを作成
- データグリッド全体にレンダラーを適用
- データグリッドのカラムではなく、データグリッド本体にitemRendererを設定するとデータグリッドの全ての列に対してレンダラーを指定したのと同じ状態になる。
ただし、副作用としてデータ行だけでなくヘッダ行も対象になってしまうので、レンダラーの中でヘッダ行を対象から除外する処理を記述しておく必要がある。
- ヘッダ行だけにレンダラーを適用したい場合は、DataGridColumn?のheaderRendererプロパティにレンダラーを指定すると良い。
- サンプルプログラム - データグリッド全体にレンダラーを適用 (実行画面はこちら)
DataGridAllRendererSample.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
creationComplete="onCreationComplete()"
>
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import dto.PersonDto;
[Bindable]
private var dataArray :Array = new Array();
[Bindable]
private var dataArrayCollection :ArrayCollection = new ArrayCollection();
private function onCreationComplete() :void
{
this.dataArray.push(new PersonDto("山田", "太郎", 21, "000-111-222", "aaa@hoge.com", "男"));
this.dataArray.push(new PersonDto("佐藤", "花子", 25, "111-222-333", "bbb@hoge.com", "女"));
this.dataArray.push(new PersonDto("スミス", "ジョン", 41, "999-111-222", "ccc@hoge.com", "男"));
this.dataArray.push(new PersonDto("斉藤", "次郎", 22, "555-111-222", "ddd@hoge.com", "男"));
this.dataArray.push(new PersonDto("鈴木", "さくら", 15, "666-111-222", "eee@hoge.com", "女"));
this.dataArrayCollection.source = this.dataArray;
}
]]>
</mx:Script>
<mx:VBox width="100%" height="100%">
<mx:DataGrid id="arrayCollectionDataGrid" dataProvider="{this.dataArrayCollection}" width="100%" itemRenderer="renderer.MyDataGridItemRenderer">
<mx:columns>
<mx:DataGridColumn headerText="姓" dataField="lastName" />
<mx:DataGridColumn headerText="名" dataField="firstName" />
<mx:DataGridColumn headerText="年齢" dataField="age" />
<mx:DataGridColumn headerText="電話番号" dataField="tel" />
<mx:DataGridColumn headerText="メールアドレス" dataField="email" />
<mx:DataGridColumn headerText="性別" dataField="gender" />
</mx:columns>
</mx:DataGrid>
</mx:VBox>
</mx:Application>
- ClassFactory?をレンダラーに指定
- レンダラーにはクラス名ではなく、mx.core.ClassFactory?クラスのインスタンスを指定することもできる。
- スクリプトで記述する場合は、itemRendererプロパティの型がmx.core.IFactory(ClassFactory?のインターフェース)なので、この方法でしか設定できない。
- タグでitemRendererプロパティにレンダラーのクラス名を指定した場合も、実際には裏でClassFactory?のインスタンスが生成されてそちらが指定されている。
- ClassFactory?とは、指定されたクラスのインスタンスを生成するためのファクトリークラスである。
- この方法の利点としては、ClassFactory?のpropertiesプロパティに初期化用オブジェクトを指定することにより、レンダラーのインスタンスを生成する際のプロパティを指定することができる。
これを使えば、レンダラーによって変化させる色などのスタイルを変更したり、レンダラー適用の条件を変更したりすることもできるので、レンダラーの応用範囲がさらに広がる。
- サンプルプログラム - ClassFactory?をレンダラーに指定 (実行画面はこちら)
DataGridClassFactoryRendererSample.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
creationComplete="onCreationComplete()"
>
<mx:Script>
<![CDATA[
import renderer.MyDataGridItemRenderer;
import mx.collections.ArrayCollection;
import dto.PersonDto;
[Bindable]
private var dataArray :Array = new Array();
[Bindable]
private var dataArrayCollection :ArrayCollection = new ArrayCollection();
[Bindable]
private var myDataGridItemRenderer :ClassFactory = null;
private function onCreationComplete() :void
{
this.myDataGridItemRenderer = new ClassFactory(MyDataGridItemRenderer);
this.myDataGridItemRenderer.properties =
{
color :0x0000FF,
borderAge: 20
};
this.telColumn.itemRenderer = this.myDataGridItemRenderer;
this.dataArray.push(new PersonDto("山田", "太郎", 21, "000-111-222", "aaa@hoge.com", "男"));
this.dataArray.push(new PersonDto("佐藤", "花子", 25, "111-222-333", "bbb@hoge.com", "女"));
this.dataArray.push(new PersonDto("スミス", "ジョン", 41, "999-111-222", "ccc@hoge.com", "男"));
this.dataArray.push(new PersonDto("斉藤", "次郎", 22, "555-111-222", "ddd@hoge.com", "男"));
this.dataArray.push(new PersonDto("鈴木", "さくら", 15, "666-111-222", "eee@hoge.com", "女"));
this.dataArrayCollection.source = this.dataArray;
}
]]>
</mx:Script>
<mx:VBox width="100%" height="100%">
<mx:DataGrid id="arrayCollectionDataGrid" dataProvider="{this.dataArrayCollection}" width="100%">
<mx:columns>
<mx:DataGridColumn headerText="姓" dataField="lastName" />
<mx:DataGridColumn headerText="名" dataField="firstName" />
<mx:DataGridColumn headerText="年齢" dataField="age" itemRenderer="{this.myDataGridItemRenderer}" />
<mx:DataGridColumn id="telColumn" headerText="電話番号" dataField="tel" />
<mx:DataGridColumn headerText="メールアドレス" dataField="email" />
<mx:DataGridColumn headerText="性別" dataField="gender" />
</mx:columns>
</mx:DataGrid>
</mx:VBox>
</mx:Application>
ViewStack?とTabNavigator? (P305 ~ P307) †
- ViewStack?
- 1つの領域の中で、条件に応じて複数のコンテナを切り替えて表示することができるViewStack?(mx.containers.ViewStack?)コンテナというものが存在する。
- 中身に直接入れられるのはコンテナだけなので、コントロールを直接入れるとおかしくなる。
- ViewStack?の中にViewStack?を入れ子にすることもできる。
- 初期状態では、一番最初に記述した中身のコンテナが表示対象となる。
- ViewStack?自体に表示対象のコンテナを切り替える機能は備わっていないため、以下のいずれかの方法と組み合わせる必要がある。
- selectedIndexプロパティを変更する。
スクリプトでViewStack?のselectedIndexプロパティに中身のコンテナのインデックスを指定すると、そのコンテナがアクティブになる。
(注)インデックスは1からではなく、0から始まるので注意。
(注)<mx:ViewStack?>タグの初期値でselectedIndexを指定してもうまく効かないので、初期化時に変更したい場合はcreationCompleteイベントで行う方が良い。
- selectedChildプロパティを変更する。
スクリプトでViewStack?のselectedChildプロパティに中身のコンテナのインスタンスを指定すると、そのコンテナがアクティブになる。
当然だが、ViewStack?の中身のコンテナ以外を指定するとエラーになる。
(注)初期化時はまだ中身のコンテナのインスタンスがViewStack?に関連づけられていないため、<mx:ViewStack?>タグの初期値でselectedChildを指定すると実行時エラーになってしまうので要注意。
- LinkButtonBar?やToggleButtonBar?と関連づける。
LinkButtonBar?やToggleButtonBar?のデータプロバイダにViewStack?のインスタンスを指定すると、それだけでViewStack?を切り替えるための仕組みを作ることができる。
ボタンに表示される名称には、中身のコンテナのlabelプロパティの値が使用される。
中身のコンテナにiconプロパティの値が指定されていると、ボタンに画像も表示される。
- デフォルトの設定だと、中身のコンテナはアクティブになるまで初期化処理が行われない。
最初から中身のコンテナの初期化処理を行いたい場合は、creationPolicyプロパティに「all」を指定する必要がある。
(意図せぬバグを未然に防ぐためには、必ずcreationPolicyプロパティに「all」を指定しておくのが無難。)
(参考URL: http://www.adobe.com/livedocs/flex/201_jp/html/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Book_Parts&file=layoutperformance_119_07.html )
- resizeToContent?プロパティにtrueを指定すると、中身のコンテナのサイズに応じてViewStack?自体のサイズも変化するようになる。
(resizeToContent?プロパティのデフォルト値はfalse)
- サンプルプログラム - ViewStack?コンテナの使用例 (実行画面はこちら)
ViewStackSample.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" xmlns:containers="containers.*">
<mx:VBox width="100%" height="100%">
<mx:HBox width="100%">
<mx:Label text="ViewStackと関連づけたLinkBar: " />
<mx:LinkBar dataProvider="{this.mainViewStack}" />
</mx:HBox>
<mx:HBox width="100%">
<mx:Label text="ViewStackと関連づけたToggleButtonBar: " />
<mx:ToggleButtonBar dataProvider="{this.mainViewStack}" />
</mx:HBox>
<mx:HBox width="100%">
<mx:Label text="ボタンでViewStackを切り替え: " />
<mx:Button label="selectedIndexを2に変更" click="this.mainViewStack.selectedIndex = 2" />
<mx:Button label="selectedChildをcontent2に変更" click="this.mainViewStack.selectedChild = this.content2" />
</mx:HBox>
<mx:ViewStack id="mainViewStack"
width="100%" height="100%"
backgroundColor="#FFFFFF"
creationPolicy="all"
>
<mx:VBox id="content1" width="100%" height="100%" label="中身その1">
<mx:Label text="中身その1の内容です" />
<mx:TextInput />
</mx:VBox>
<mx:Panel id="content2" width="100%" height="100%" label="中身その2" title="パネルです">
<mx:Label id="myLabel" text="中身その2の内容です" />
<mx:CheckBox label="チェックボックス" />
</mx:Panel>
<containers:MyContainer id="content3" width="100%" height="100%" label="自分で作ったコンテナ" />
<mx:ViewStack id="subViewStack"
width="100%" height="100%"
label="入れ子のViewStack"
creationPolicy="all"
>
<mx:VBox width="100%" height="100%" label="入れ子のViewStackの中身その1">
<mx:Label text="入れ子のViewStackの中身その1の内容です" />
<mx:Button label="次のページ" click="this.subViewStack.selectedIndex = 1" />
</mx:VBox>
<mx:VBox width="100%" height="100%" label="入れ子のViewStackの中身その2">
<mx:Label text="入れ子のViewStackの中身その2の内容です" />
<mx:Button label="前のページ" click="this.subViewStack.selectedIndex = 0" />
</mx:VBox>
</mx:ViewStack>
</mx:ViewStack>
</mx:VBox>
</mx:Application>
ViewStack?の中身に入れられている自作のコンテナクラス - containers.MyContainer.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml"
creationComplete="onCreationComplete()"
>
<mx:Script>
<![CDATA[
import mx.controls.Alert;
private function onCreationComplete() :void
{
Alert.show("自分で作ったコンテナクラスが初期化されました");
}
]]>
</mx:Script>
<mx:Label text="自分で作ったコンテナクラス" />
<mx:TextArea text="あいうえお" />
</mx:VBox>
- TabNavigator?
- ViewStack?にタブをつけて、自分自身に中身のコンテナの切り替え機能を備えたTabNavigator?(mx.containers.TabNavigator?)コンテナというものが存在する。
- タブ部分をクリックするとビューが切り替わる。
- タブに表示される名称には、中身のコンテナのlabelプロパティの値が使用される。
- ViewStack?を継承しているので同じインターフェースで使用できる。
- サンプルプログラム - TabNavigator?コンテナの使用例 (実行画面はこちら)
TabNavigatorSample.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" xmlns:containers="containers.*">
<mx:VBox width="100%" height="100%">
<mx:HBox width="100%">
<mx:Label text="TabNavigatorと関連づけたLinkBar: " />
<mx:LinkBar dataProvider="{this.mainTabNavigator}" />
</mx:HBox>
<mx:HBox width="100%">
<mx:Label text="TabNavigatorと関連づけたToggleButtonBar: " />
<mx:ToggleButtonBar dataProvider="{this.mainTabNavigator}" />
</mx:HBox>
<mx:HBox width="100%">
<mx:Label text="ボタンでTabNavigatorを切り替え: " />
<mx:Button label="selectedIndexを2に変更" click="this.mainTabNavigator.selectedIndex = 2" />
<mx:Button label="selectedChildをcontent2に変更" click="this.mainTabNavigator.selectedChild = this.content2" />
</mx:HBox>
<mx:TabNavigator id="mainTabNavigator"
width="100%" height="100%"
backgroundColor="#FFFFFF"
creationPolicy="all"
>
<mx:VBox id="content1" width="100%" height="100%" label="中身その1">
<mx:Label text="中身その1の内容です" />
<mx:TextInput />
</mx:VBox>
<mx:Panel id="content2" width="100%" height="100%" label="中身その2" title="パネルです">
<mx:Label id="myLabel" text="中身その2の内容です" />
<mx:CheckBox label="チェックボックス" />
</mx:Panel>
<containers:MyContainer id="content3" width="100%" height="100%" label="自分で作ったコンテナ" />
<mx:TabNavigator id="subTabNavigator"
width="100%" height="100%"
label="入れ子のTabNavigator"
creationPolicy="all"
>
<mx:VBox width="100%" height="100%" label="入れ子のTabNavigatorの中身その1">
<mx:Label text="入れ子のTabNavigatorの中身その1の内容です" />
<mx:Button label="次のページ" click="this.subTabNavigator.selectedIndex = 1" />
</mx:VBox>
<mx:VBox width="100%" height="100%" label="入れ子のTabNavigatorの中身その2">
<mx:Label text="入れ子のTabNavigatorの中身その2の内容です" />
<mx:Button label="前のページ" click="this.subTabNavigator.selectedIndex = 0" />
</mx:VBox>
</mx:TabNavigator>
</mx:TabNavigator>
</mx:VBox>
</
|