Flex中DataGrid内嵌CheckBox的全选反选和防止选择状态错乱实现方法
从网上搜索相关的资料绝大多数全选和反选实现方式是通过继承DataGrid和CheckBox来在子类里面实现一些方法来实现,而这些方法大多数都是对事件进行监听来实现全选反选.这种方式很好,但是个人认为很麻烦,而且如果是一个已经成型的系统要加全选反选功能的话,会变得挺复杂和麻烦.
再就是DataGrid中内嵌CheckBox的时候,如果出现滚动条,在拖动之后,之前的选择状态会变混乱,从网上找到解决方法就是把复选框的状态保存在一个数组类型的结构中.
正巧本人用到了上面两个问题的解决,如果把它们一块解决的话,会使得全选反选的方法变得很简单.
下面请看代码:
package
{
[Bindable]//此类必须是可绑定的//用于存放数据
public class DataObject
{
public var index:Number;
public var selected:Boolean = false;//存放复选框的状态
public var phone:String;
public var name:String;
}
}
上面的代码用于存放数据,值得注意的是,selected属性用来存放复选框的状态.其他的是业务数据.
<?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>
第二段代码是使用方式,可以直接运行的,放在自己的flash builder中一运行就明白了.
注意:obj用于存放datagrid中的所有数据,以及所有复选框的状态,作为datagrid的dataProvider传入其中.
而在复选框内设置它的选中状态属性为selected="{data.selected}",则可以使它的状态与obj中的相应数据对象的selected属性相对应.
如此便可以防止在出现滚动条拖动的时候复选框状态变乱的问题了.
而且,要实现全选反选等操作也就变成了对obj进行的操作了,而不是直接对CheckBox进行操作,会容易许多,不再详述,请查看代码.
附源代码,放到src根目录即可无错误执行.