这里例子将展示如何使用用户自定义的item renderer来设置DataGrid中行被选择的风格。看看这个例子:
我们先搭建一个基本的界面结构:一个只有几个列的DataGrid。
<?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" width="300" height="125"> <mx:DataGrid width="100%" height="100%"> <mx:columns> <mx:DataGridColumn headerText="First Name" dataField="firstName"/> <mx:DataGridColumn headerText="Last Name" dataField="lastName"/> <mx:DataGridColumn headerText="Age" dataField="age"/> <mx:DataGridColumn headerText="Sex" dataField="sex"/> </mx:columns> </mx:DataGrid> </mx:Application>
然后,还要导入一些初始的数据到DataGrid中。这里是在在程序加载初始化的时候即creationComplete函数执行的时候调用我们导入数据的函数init()。
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" width="300" height="125" creationComplete="init()">
方法中增加了一些变量,这些变量对应grid中的datafield。具体如下:
<mx:Script> <![CDATA[ import mx.collections.ArrayCollection; [Bindable] private var peeps:ArrayCollection; private function init():void { peeps = new ArrayCollection(); peeps.addItem({firstName: "Handsome", lastName: "Dude", age: 24, sex: "male"}); peeps.addItem({firstName: "Red", lastName: "Bloke", age: 25, sex: "male"}); peeps.addItem({firstName: "Tall", lastName: "Guy", age: 25, sex: "male"}); peeps.addItem({firstName: "Cute", lastName: "Girl", age: 24, sex: "female"}); peeps.addItem({firstName: "Hot", lastName: "Chick", age: 24, sex: "female"}); peeps.addItem({firstName: "Lazy", lastName: "Man", age: 25, sex: "male"}); } ]]> </mx:Script>
要使得这些数据现实在grid中,我们必须设定DataGrid中的dataProvider属性指向这个数据源:
<mx:DataGrid dataProvider="{peeps}" width="100%" height="100%">
最有意思的部分在于当我们选择了某个行的时候要创建一个自定义的itemRender.这里例子当中我们要创建的自定义组件是一个Label。要使得这个Label可用,我们必须重写Label的set data函数。把Label的text内容设置成为某个dataField的属性值。从我们的renderer的listData属性中取得dataField属性名。自定义的Renderer为:
<?xml version="1.0" encoding="utf-8"?> <mx:Label xmlns:mx="http://www.adobe.com/2006/mxml" width="100%" height="100%"> <mx:Script> <![CDATA[ import mx.controls.dataGridClasses.DataGridListData; override public function set data(value:Object):void { super.data = value; if(value) { var dglistData:DataGridListData = listData as DataGridListData; if(value[dglistData.dataField]) this.text = value[dglistData.dataField]; } } ]]> </mx:Script> </mx:Label>
这里我们所做的只是创建一个很贱的item Renderer。要弄清这个Renderer是否是我们所选的行,我们必须检查这个Renderer的Data是否对应DataGrid中被选中行的数据。为此,我们又在init中设置了对DataGrid事件的监听。下面是全部的CustomRenderer.mxml
<?xml version="1.0" encoding="utf-8"?> <mx:Label xmlns:mx="http://www.adobe.com/2006/mxml" width="100%" height="100%" creationComplete="init()"> <mx:Script> <![CDATA[ import mx.events.ListEvent; import mx.controls.DataGrid; import mx.controls.dataGridClasses.DataGridListData; private var dg:DataGrid; private function init():void { dg = listData.owner as DataGrid; dg.addEventListener(ListEvent.CHANGE, updateSelected); } override public function set data(value:Object):void { super.data = value; if(value) { var dglistData:DataGridListData = listData as DataGridListData; if(value[dglistData.dataField]) this.text = value[dglistData.dataField]; updateSelected(); } } private function updateSelected(e:Event = null):void { if(!data || !dg) return; if(dg.selectedItem == data) { //This row is selected update stuff setStyle("fontWeight", "bold"); } else { //This row is not selected reset stuff setStyle("fontWeight", "normal"); } } ]]> </mx:Script> </mx:Label>
首先,我为DataGrid增加了一个变量dg,在inti函数中,我们使用了之前提过的listData设置了gird变量等于这个renderer的owner.然后我们添加了一个事件,能够响应选择事件并且调用了updateSelected函数。这个函数检查这一行,并且更新了显示的风格。当然,当另外一行被选择之后,当前的选择行的风格必须也随着改变,即恢复初始的状态。
代码下载:http://www.switchonthecode.com/sites/default/files/244/source/SOTC-DataGridSelectedRow.zip
Original Paper:http://www.switchonthecode.com/tutorials/flex-datagrid-selected-row-styling