对用户来讲,软件的功能性之外还要求其易用习惯性。非专业用户习惯了用鼠标点而不大适应键盘+鼠标。Flex的DataGrid虽然可以允许用户多选项目,但是这个多选需要结合Ctrl或Shift键来完成。而我们去网上浏览下歌曲网站在选择多首歌曲的过程就知道用户更喜欢那种方式了。
本文简单实现在DataGrid中结合CheckBox完成对项目的选择、全选和反选功能。但它并不十分适合组件化,应付一下特例还是可以的,但其是可以优化的。
效果如下图所示:
组件DataGridCheckBox.mxml代码如下所示:
<?xml version="1.0" encoding="utf-8"?> <s:Group 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[ import mx.collections.ArrayCollection; import mx.controls.Alert; //数据源 private var dsObjects:ArrayCollection = new ArrayCollection([ {flag:false,name:"Chen",job:"developer"}, {flag:false,name:"men",job:"mentor"}, ]); /* *实现所有项目的全选中过程 */ public function all_click(event:Event):void{ dsObjects = this.dgDistbRecordSearchList.dataProvider as ArrayCollection; this.unAll.selected = false; for(var i:int = 0 ;i<dsObjects.length;i++){ dsObjects[i].flag = CheckBox(event.target).selected; } //重新绑定 this.dgDistbRecordSearchList.dataProvider = dsObjects; } /* *实现项目反相选中 */ public function unAll_click(event:Event):void{ if(CheckBox(event.target).selected){ this.all.selected = false; dsObjects = this.dgDistbRecordSearchList.dataProvider as ArrayCollection; for(var i:int = 0 ;i<dsObjects.length;i++){ dsObjects[i].flag = !dsObjects[i].flag; } //重新绑定 this.dgDistbRecordSearchList.dataProvider = dsObjects; } } //显示被选中项目的名称 private function showSelectedName():void{ var ac:ArrayCollection = this.dgDistbRecordSearchList.dataProvider as ArrayCollection; var selectedNames = "选中项目名称为:" for(var i:int = 0;i<ac.length;i++){ if(ac[i].flag == true){ selectedNames += ac[i].name + " "; } } Alert.show(selectedNames); } ]]> </fx:Script> <mx:VBox> <mx:DataGrid id="dgDistbRecordSearchList" width="100%" height="100%" allowMultipleSelection="true" dataProvider="{dsObjects}" > <mx:columns> <mx:DataGridColumn headerText="选择" width="42" > <mx:itemRenderer > <fx:Component > <mx:HBox horizontalAlign="center"> <mx:CheckBox selected="@{data.flag}" change="checkbox1_changeHandler(event,data)" width="13"> <fx:Script> <![CDATA[ import mx.events.ListEvent; protected function checkbox1_changeHandler(event:Event,obj:Object):void { //调整按钮选择性 outerDocument.unAll.selected = false; outerDocument.all.selected = false; //在单向绑定时可采用此法将选中信息反应到数据源 /* obj.flag = CheckBox(event.target).selected; */ } ]]> </fx:Script> </mx:CheckBox> </mx:HBox> </fx:Component> </mx:itemRenderer> </mx:DataGridColumn> <mx:DataGridColumn id="nam" textAlign="left" headerText="姓名" dataField="name"/> <mx:DataGridColumn id="job" textAlign="left" headerText="职位" width="80" dataField="job"/> </mx:columns> </mx:DataGrid> <mx:HBox> <s:CheckBox id="all" label="全选" width="45" height="30" click="all_click(event)"/> <s:CheckBox id="unAll" label="反选" width="45" height="30" click="unAll_click(event)"/> </mx:HBox> <mx:Button label="选中项目的名称" click="showSelectedName()" /> </mx:VBox> </s:Group>该代码仅作为项目实践的代码原理模型,存在很多不足,例如数据源是固定在组件内部的,同时作为数据源的类中包含了一个flag属性,它主要用于控制dataGrid中的项目是否被选中,而实际中这个数据源应该是业务数据,而这个flag标识很可能在业务上是无需存在的。但这个组件提供了一个基本的实现思路,其前途在于对其进行改造,使之成为可以复用的控件。
同时,注意DataGrid中的项目被选中后,在业务上往往是要有后续操作的,这个需求在这个模型中表现在Button("选中项目的名称")上,点击后会弹出选中项目的名称,其实现可以通过双向绑定(71L),也可以手动更新数据源(81L)。
此模型的关键不仅在提供一种实现思路,更在提示要在实现的基础上继续挖掘,要从残缺中积累出完美!