在DataGrid中实现列中加入CheckBox这种用法很常见,项目中也经常会用到,在网上搜了下基本就是实现itemRender.但是 感觉网上提供的实现上好些地方都是多余的 经过自己的改造感觉还行 附上代码,同时希望大家举一反三 能实现添加其他组件到DataGrid列中
第一种方法:编写两个项选择器,继承CheckBox的方法,在DataGridview控件中的DataGridColumn列的属性headerRenderer,itemRenderer写入项选择器
CheckBoxHeaderRenderer.as
<pre class="java" name="code">package { import flash.events.Event; import flash.events.MouseEvent; import mx.collections.ArrayCollection; import mx.controls.Alert; import mx.controls.CheckBox; import mx.controls.DataGrid; import mx.events.DataGridEvent; public class CheckBoxHeaderRenderer extends CheckBox { private var sele:String; public function CheckBoxHeaderRenderer() { super(); this.addEventListener(Event.CHANGE, clickHandlers); } override public function set data(value:Object):void { DataGrid(listData.owner).addEventListener (DataGridEvent.HEADER_RELEASE,sortEventHandler); this.selected=this.sele=="true"?true:false; } private function sortEventHandler(event:DataGridEvent):void { if (event.itemRenderer == this) event.preventDefault(); } protected function clickHandlers(event:Event):void { sele=(event.currentTarget.selected).toString(); var a:ArrayCollection=DataGrid(listData.owner).dataProvider as ArrayCollection; for(var i:int=0;i<a.length;i++){ (DataGrid(listData.owner).dataProvider as ArrayCollection) .getItemAt(i).selected=(event.currentTarget.selected).toString(); } (DataGrid(listData.owner).dataProvider as ArrayCollection).refresh(); } } }
CheckBoxItemDataRenderer.as
package { import flash.events.Event; import mx.collections.ArrayCollection; import mx.controls.CheckBox; import mx.controls.DataGrid; public class CheckBoxItemDataRenderer extends CheckBox { private var currentData:Object; //保存当前一行值的对象 public function CheckBoxItemDataRenderer() { super(); this.addEventListener(Event.CHANGE, changeHandler); } override public function set data(value:Object):void { this.currentData= value; this.selected = value.selected == "true"?true:false; } protected function changeHandler(event : Event) : void { currentData.selected = this.selected.toString(); } /*override public function get data():Object{ return currentData; }*/ } }
DataGrid_Checkbox.mxml
<?xml version="1.0" encoding="utf-8"?> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:dataGrid="*" minWidth="955" minHeight="600" creationComplete="getaa()"> <fx:Script> <![CDATA[ import mx.collections.ArrayCollection; import mx.controls.Alert; [Bindable] private var data_myDataGrid:ArrayCollection=new ArrayCollection(); private function headerClickHandler(event : Event) : void { /* for each(var obj: Object in data_myDataGrid) { obj.selected = String(event.currentTarget.selected); } data_myDataGrid.refresh(); */ } private function getaa():void{ var obj:Object=new Object(); obj.labe="1"; obj.data="a"; obj.selected="false"; var obj2:Object=new Object(); obj2.labe="2"; obj2.data="b"; obj2.selected="false"; var obj3:Object=new Object(); obj3.labe="3"; obj3.data="c"; obj3.selected="false"; var obj4:Object=new Object(); obj4.labe="4"; obj4.data="a"; obj4.selected="false"; var obj5:Object=new Object(); obj5.labe="5"; obj5.data="b"; obj5.selected="false"; var obj6:Object=new Object(); obj6.labe="6"; obj6.data="c"; obj6.selected="false"; var obj7:Object=new Object(); obj7.labe="7"; obj7.data="a"; obj7.selected="false"; var obj8:Object=new Object(); obj8.labe="8"; obj8.data="b"; obj8.selected="false"; var obj9:Object=new Object(); obj9.labe="9"; obj9.data="c"; obj9.selected="false"; data_myDataGrid.addItem(obj); data_myDataGrid.addItem(obj3); data_myDataGrid.addItem(obj2); data_myDataGrid.addItem(obj4); data_myDataGrid.addItem(obj5); data_myDataGrid.addItem(obj6); data_myDataGrid.addItem(obj7); data_myDataGrid.addItem(obj8); data_myDataGrid.addItem(obj9); } protected function button1_clickHandler(event:MouseEvent):void { for(var i:int=0;i<data_myDataGrid.length;i++){ if(data_myDataGrid.getItemAt(i).selected=='true'){ Alert.show(data_myDataGrid.getItemAt(i).labe); } } } ]]> </fx:Script> <mx:DataGrid dataProvider="{data_myDataGrid}" x="10" y="10"> <mx:columns> <mx:DataGridColumn dataField="labe" headerText="Label" /> <mx:DataGridColumn dataField="data" headerText="Data" /> <mx:DataGridColumn dataField="selected" headerText="Select" itemRenderer="CheckBoxItemDataRenderer" headerRenderer="CheckBoxHeaderRenderer" /> </mx:columns> </mx:DataGrid> <mx:Button click="button1_clickHandler(event)"/> </s:Application>
第二种方法: 不继承checkBox类,直接在DataGrid中的DataGridColumn列中编写属性,项选择器,并写点击事件
用于存放数据的类,值得注意的是,selected属性用来存放复选框的状态.其他的是业务数据
package { [Bindable]//此类必须是可绑定的//用于存放数据 public class DataObject { public var index:Number; public var selected:Boolean = false;//<span style="font-family: Helvetica, Tahoma, Arial, sans-serif; white-space: normal; background-color: rgb(255, 255, 255);">存放复选框的状态</span> public var phone:String; public var name:String; } }
应用程序
<?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" xmlns:ns1 ="com.common.*" creationComplete="application1_creationCompleteHandler(event)"> <mx:Script> <![CDATA[ import mx.collections.ArrayCollection; import mx.controls.Alert; import mx.core.UIComponent; import mx.events.DragEvent; import mx.events.FlexEvent; import mx.events.ListEvent; [Bindable] public var obj:ArrayCollection;//用于存放datagrid中的所有数据,以及所有复选框的状态 [Bindable] public var nums:String=""; protected function application1_creationCompleteHandler(event:FlexEvent):void { // TODO Auto-generated method stub var arr:ArrayCollection = new ArrayCollection(); for(var i:Number=0;i<20;i++) { var o:DataObject = new DataObject(); o.selected=false; o.index = i; o.name = "test"+(i+1); o.phone = "10010-"+(i+1); arr.addItem(o); } setData(arr); } public function setData(arr:ArrayCollection):void { if(arr.length>0) { this.obj=arr ; } } private function call():void { Alert.show(getSelectedObjects().toString()); } private function getSelectedObjects():ArrayCollection { var selectedObjects:ArrayCollection=new ArrayCollection(); if(obj.length>0) { for(var i:Number=0;i<obj.length;i++) { var o:DataObject = obj.getItemAt(i) as DataObject; if(o.selected) { selectedObjects.addItem(o.phone); } } } return selectedObjects; } protected function checkbox2_changeHandler(event:Event):void { var slc:Boolean = selectAllCheckBox.selected; if(obj.length>0) { for(var i:Number=0;i<obj.length;i++) { obj.getItemAt(i).selected=slc; } } } protected function checkbox3_changeHandler(event:Event):void { if(obj.length>0) { for(var i:Number=0;i<obj.length;i++) { obj.getItemAt(i).selected=!obj.getItemAt(i).selected; } } } ]]> </mx:Script> <mx:VBox> <mx:DataGrid id="dg" width="100%" height="300" dataProvider="{obj}"> <mx:columns> <mx:DataGridColumn width="16"> <mx:itemRenderer> <mx:Component> <mx:CheckBox selected="{data.selected}" change="checkbox1_changeHandler(event)"> <mx:Script> <![CDATA[ protected function checkbox1_changeHandler(event:Event):void {//将复选框的状态保存在obj中,防止出现复选框错乱的情况 outerDocument.obj.getItemAt(outerDocument.dg.selectedIndex).selected=event.target.selected; } ]]> </mx:Script> </mx:CheckBox> </mx:Component> </mx:itemRenderer> </mx:DataGridColumn> <mx:DataGridColumn headerText="名称" dataField="name"/> <mx:DataGridColumn headerText="电话" dataField="phone"/> </mx:columns> </mx:DataGrid> <mx:HBox> <mx:CheckBox label="全选" id="selectAllCheckBox" change="checkbox2_changeHandler(event)"/> <mx:CheckBox label="反选" change="checkbox3_changeHandler(event)"/> </mx:HBox> <mx:Button label="呼叫" click="call()"/> </mx:VBox> </mx:Application>
运行即可。此方法,用全选和反选,不过全选和反选按钮是单独存在,不在Datagrid内
第三种方法
VO
package vos { [Bindable] public class TestVO { public function TestVO() { } public var id:String; public var label:String; public var icon:String; [Transient] public var selected:Boolean = false; } }
<?xml version="1.0" encoding="utf-8"?> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx"> <s:layout> <s:VerticalLayout paddingTop="5" paddingBottom="5" paddingLeft="5" paddingRight="5" gap="5" horizontalAlign="center" verticalAlign="middle"/> </s:layout> <fx:Script> <![CDATA[ import mx.collections.ArrayCollection; import mx.events.FlexEvent; import vos.TestVO; [Bindable] private var dp:ArrayCollection; private function createData():void { dp = new ArrayCollection(); for (var i:int = 0; i < 10; i++) { var t:TestVO = new TestVO(); t.id = String(i); t.label = "label" + i; t.icon = "assets/icons/" + i + ".png"; t.selected = (Math.random() > .5) ? true : false; dp.addItem(t); } } private function deleteData():void { for (var i:int = dp.length - 1; i >= 0; i--) { var t:TestVO = dp.getItemAt(i) as TestVO; if(t.selected) dp.removeItemAt(i); } } public function selectAll(event:MouseEvent):void { var cb:mx.controls.CheckBox = event.currentTarget as mx.controls.CheckBox; if(!dp) { //还没数据的时候,你就别选中了,没用 cb.selected = false; return; } for each (var t:TestVO in dp) { t.selected = cb.selected; } } >> </fx:Script> <fx:Declarations> <!-- 将非可视元素(例如服务、值对象)放在此处 --> </fx:Declarations> <mx:DataGrid id="dg" width="400" height="300" dataProvider="{dp}"> <mx:columns> <mx:DataGridColumn width="20" sortable="false"> <mx:headerRenderer> <fx:Component> <mx:CheckBox click="outerDocument.selectAll(event)"/> </fx:Component> </mx:headerRenderer> <mx:itemRenderer> <fx:Component> <mx:CheckBox selected="@{data.selected}"/> </fx:Component> </mx:itemRenderer> </mx:DataGridColumn> <mx:DataGridColumn dataField="label"/> <mx:DataGridColumn dataField="icon"/>a </mx:columns> </mx:DataGrid> <s:HGroup> <s:Button label="create data" click="createData()"/> <s:Button label="delete selected data" click="deleteData()"/> </s:HGroup> </s:Application>
几个可能有疑问的地方:
(1)selected="@{data.selected}", "@"的作用是双向绑定,当data.selected改变时,checkbox的selected也随之改变,反之亦然。
(2)[Transient] 作用是指定接下来的字段在序列化的时候可以忽略。比如与后台交互的时候,后台vo不需要selected这个字段,加上它就行了(不加可能会导致警告)。
(3)例子里的CheckBox没有居中,如果要让它居中可以给它包上一个居中的容器。
用Hbox包一下就行了 <mx:DataGridColumn width="20" sortable="false" textAlign="center"> <mx:headerRenderer> <fx:Component> <mx:HBox horizontalAlign="center" verticalAlign="middle"> <mx:CheckBox click="outerDocument.selectAll(event)"/> </mx:HBox> </fx:Component> </mx:headerRenderer> <mx:itemRenderer> <fx:Component> <mx:HBox horizontalAlign="center" verticalAlign="middle"> <mx:CheckBox selected="@{data.selected}"/> </mx:HBox> </fx:Component> </mx:itemRenderer> </mx:DataGridColumn>