DataGridとComboBoxつかうためのサンプル

DataGridの選択エリアにComboBoxを使おうと思って試行錯誤したときのメモ。知らないと難しい...

何も考えないで実装するとこう

以下のようなソースのときに、"sex"カラムが、持っている値は 0 or 1だけど、男性・女性とComboBoxで編集できるようにすることがゴール。

<?xml version="1.0"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
	<mx:Script>
		<![CDATA[
		import mx.controls.*;
		import mx.collections.*;

		[Bindable]
		public var list:ArrayCollection =  new ArrayCollection(
			[ { no:1, name:"Taro", sex: 1 }, { no:2, name:"Hanako", name:"Hanako", sex: 0 } ]
		);
		]]>
	</mx:Script>

	<mx:DataGrid width="100%" height="100%" dataProvider="{list}">
		<mx:columns>
			<mx:DataGridColumn dataField="no" />
			<mx:DataGridColumn dataField="name" />
			<mx:DataGridColumn dataField="sex" />
		</mx:columns>
	</mx:DataGrid>

</mx:Application>

labelFunctionを使ってみる

labelFunctionを使うことによって、0→女性。1→男性のようにlabel表記を処理することができます。

<?xml version="1.0"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns="*">
	<mx:Script>
		<![CDATA[
		import mx.controls.*;
		import mx.collections.*;
		import mx.controls.dataGridClasses.DataGridColumn;

		public function getSexname(item:Object, column:DataGridColumn):String
		{
			var type:Number = item.sex;
			return (type == 0) ? "女性" : "男性";
		};

		[Bindable]
		public var list:ArrayCollection =  new ArrayCollection(
			[ { no:1, name:"Taro", sex: 1 }, { no:2, name:"Hanako", name:"Hanako", sex: 0 } ]
		);
		]]>
	</mx:Script>

	<mx:DataGrid width="100%" height="100%" dataProvider="{list}" editable="true">
		<mx:columns>
			<mx:DataGridColumn dataField="no" editable="false" />
			<mx:DataGridColumn dataField="name" editable="false" />
			<mx:DataGridColumn dataField="sex" labelFunction="{getSexname}" />
		</mx:columns>
	</mx:DataGrid>

</mx:Application>

itemEditorを使う

で、最後に。itemEditorを使っています。itemRendererを使う方法もあるんがけどそれは置いておきます...。 editorDataField="value"と、itemEditorに自作のmxmlを置いているのがポイントでしょうか...。

main.mxml
<?xml version="1.0"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns="*">
	<mx:Script>
		<![CDATA[
		import mx.controls.*;
		import mx.collections.*;
		import mx.controls.dataGridClasses.DataGridColumn;

		public function getSexname(item:Object, column:DataGridColumn):String
		{
			var type:Number = item.sex;
			return (type == 0) ? "女性" : "男性";
		};

		[Bindable]
		public var list:ArrayCollection =  new ArrayCollection(
			[ { no:1, name:"Taro", sex: 1 }, { no:2, name:"Hanako", name:"Hanako", sex: 0 } ]
		);
		]]>
	</mx:Script>

	<mx:DataGrid width="100%" height="100%" dataProvider="{list}" editable="true">
		<mx:columns>
			<mx:DataGridColumn dataField="no" editable="false" />
			<mx:DataGridColumn dataField="name" editable="false" />
			<mx:DataGridColumn dataField="sex" labelFunction="{getSexname}" editorDataField="value" itemEditor="SexEditor" />
		</mx:columns>
	</mx:DataGrid>

</mx:Application>

SexEditor.mxml

編集できるようにitemEditorにカスタマイズした、ComboBoxを指定します。

<?xml version="1.0"?>
<mx:ComboBox  xmlns:mx="http://www.adobe.com/2006/mxml">
	<!-- creationCompleteでComboBoxの初期値を設定しています。 -->
	<mx:creationComplete>
	<![CDATA[
	for(var i:int=0, f:int=dataProvider.length; i<f; i++)
	{
		if(dataProvider[i].data == data.sex)
		{
			selectedIndex = i;
			break;
		};
	};
	]]>
	</mx:creationComplete>
	<mx:dataProvider>
		<mx:Array>
			<mx:Object data="0" label="女性" />
			<mx:Object data="1" label="男性" />
		</mx:Array>
	</mx:dataProvider>
</mx:ComboBox>
あと、Object#dataではなく、Object#fooを使う場合

dataProviderの値にdataではなく、fooを使う場合のソースコードは次の通りです。SexEditor.mxmlのみ変更で対応。

<?xml version="1.0"?>
<mx:ComboBox  xmlns:mx="http://www.adobe.com/2006/mxml">
	<mx:Script>
	<![CDATA[
	public override function get value():Object{
		return selectedItem.foo;
	};
	]]>
	</mx:Script>
	<mx:creationComplete>
	<![CDATA[
	for(var i:int=0, f:int=dataProvider.length; i<f; i++)
	{
		if(dataProvider[i].foo == data.sex)
		{
			selectedIndex = i;
			break;
		};
	};
	]]>
	</mx:creationComplete>
	<mx:dataProvider>
		<mx:Array>
			<mx:Object foo="0" label="女性" />
			<mx:Object foo="1" label="男性" />
		</mx:Array>
	</mx:dataProvider>
</mx:ComboBox>