最近在尝试着用Flex做个文件按管理的工具,在文件列表中为了操作方便,想到了再列表控件DataGird中添加一个含有复选框的列,在表头的复选框可以实现全选功能,但DataGird自身并无此功能。参照网上的相关资料,总算折腾出来了,现把源码奉上,希望对需要的朋友有点帮助,不足之处也请高手指点。

最终的CheckBoxColumn包包含四个相关的类文件,分别是:

1、CenterCheckBox.as:通过重写CheckBox基类来实现复选框的居中显示;

2、CheckBoxColumn.as:继承自DataGridColumn的一个新类,为了实现需要,增添了几个新属性;

3、CheckBoxHeaderRenderer.as:继承自CenterCheckBox 类,用于DataGrid表头的复选框,实现全选功能;

4、CheckBoxItemRenderer.as:继承自CenterCheckBox 类,用于DataGrid表中的数据行;

各文件源码如下:
1、CenterCheckBox.as

 
  1. package Common.YotuoUpload.CheckBoxColumn
  2. {
  3. import flash.display.DisplayObject;
  4. import mx.controls.CheckBox;
  5. import flash.text.TextField;
  6.  
  7. public class CenterCheckBox extends CheckBox
  8. {
  9. // 居中展现
  10. override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
  11. {
  12. super.updateDisplayList(unscaledWidth, unscaledHeight);
  13. var n:int = numChildren;
  14. for(var i:int = 0; i < n; i++)
  15. {
  16. var c:DisplayObject = getChildAt(i);
  17. if( !(c is TextField))
  18. {
  19. c.x = Math.round((unscaledWidth - c.width) / 2);
  20. c.y = Math.round((unscaledHeight - c.height) /2 );
  21. }
  22. }
  23. }
  24. }
  25. }

2、DataGridColumn.as

 
  1. package Common.YotuoUpload.CheckBoxColumn
  2. {
  3. import mx.controls.dataGridClasses.DataGridColumn;
  4.  
  5. public class CheckBoxColumn extends DataGridColumn{
  6.  
  7. public var cloumnSelected:Boolean=false;//保存该列是否全选的属性(用户先点击全选后在手动的取消几行数据的选中状态时,这里的状态不会改变)
  8.  
  9. public var selectItems:Array = new Array();//用户保存用户选中的数据
  10.  
  11.  
  12. public function CheckBoxColumn(columnName:String=null){
  13. super(columnName);
  14. }
  15. }
  16. }

3、CheckBoxHeaderRenderer.as

 
  1. package Common.YotuoUpload.CheckBoxColumn
  2. {
  3. import flash.events.Event;
  4.  
  5. import mx.collections.ArrayCollection;
  6. import mx.controls.CheckBox;
  7. import mx.controls.DataGrid;
  8.  
  9. public class CheckBoxHeaderRenderer extends CenterCheckBox{
  10.  
  11. private var _data:CheckBoxColumn;//定义CheckBox列对象
  12. public function CheckBoxHeaderRenderer(){
  13. super();
  14. this.addEventListener(Event.CHANGE,onChange);//CheckBox状态变化时触发此事件
  15. this.toolTip = "全选";
  16. }
  17.  
  18.  
  19. override public function get data():Object{
  20. return _data;//返回的是CheckBox列的对象
  21.  
  22. }
  23.  
  24. override public function set data(value:Object):void{
  25. _data = value as CheckBoxColumn;
  26. //trace(_data.cloumnSelected);
  27. selected = _data.cloumnSelected;
  28. }
  29.  
  30. private function onChange(event:Event):void{
  31.  
  32. var dg:DataGrid = DataGrid(listData.owner);//获取DataGrid对象
  33. var column:CheckBoxColumn = dg.columns[listData.columnIndex];//获取整列的显示对象
  34.  
  35. var dgDataArr:ArrayCollection = dg.dataProvider as ArrayCollection;
  36.  
  37. column.cloumnSelected = this.selected;//更改列的全选状态
  38.  
  39. column.selectItems = new Array();//重新初始化用于保存选中列的对象
  40.  
  41. if(this.selected){//如果为全部选中的化就将数据源赋值给column.selectItems,不是就不管他,上一步已经初始化为空
  42. column.selectItems = (dg.dataProvider as ArrayCollection).toArray();
  43.  
  44. }
  45. if(dgDataArr.length>0){
  46. if(dgDataArr[0]!=""){
  47. for(var i:int = 0; i < dgDataArr.length ; i++){
  48. Object(dgDataArr[i]).dgSelected = this.selected;//更改没一行的选中状态
  49. }
  50. }
  51. }
  52. dgDataArr.refresh();//刷新数据源,达到强制更新页面显示效果的功能,防止在使用时没有在VO类中使用绑定而出现点击全选页面没有更改状态的错误
  53. }
  54. }
  55. }

4、CheckBoxItemRenderer.as

 
  1. package Common.YotuoUpload.CheckBoxColumn
  2. {
  3. import flash.events.Event;
  4. import flash.events.MouseEvent;
  5. import mx.controls.CheckBox;
  6. import mx.controls.DataGrid;
  7.  
  8. public class CheckBoxItemRenderer extends CenterCheckBox{
  9. private var currentData:Object; //保存当前一行值的对象
  10.  
  11. public function CheckBoxItemRenderer(){
  12. super();
  13. this.addEventListener(Event.CHANGE,onClickCheckBox);
  14. this.toolTip = "选择";
  15. }
  16.  
  17. override public function set data(value:Object):void{
  18. this.selected = value.dgSelected;
  19. this.currentData = value; //保存整行的引用
  20. }
  21.  
  22. //点击check box时,根据状况向selectedItems array中添加当前行的引用,或者从array中移除
  23. private function onClickCheckBox(e:Event):void{
  24. var dg:DataGrid = DataGrid(listData.owner);//获取DataGrid对象
  25. var column:CheckBoxColumn = dg.columns[listData.columnIndex];//获取整列的显示对象
  26. var selectItems:Array = column.selectItems;
  27. this.currentData.dgSelected = this.selected;//根据是否选中的状态,更改数据源中选中的标记
  28. if(this.selected){
  29. selectItems.push(this.currentData);
  30. }else{
  31. for(var i:int = 0; i<selectItems.length; i++){
  32. if(selectItems[i] == this.currentData){
  33. selectItems.splice(i,1)
  34. }
  35. }
  36. }
  37. }
  38. }
  39. }

调用示例:

1、在mxml中作为控件调用:

 
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
  3. xmlns:s="library://ns.adobe.com/flex/spark"
  4. xmlns:mx="library://ns.adobe.com/flex/halo" minWidth="1024" minHeight="768"
  5. xmlns:CheckBoxColumn="Common.YotuoUpload.CheckBoxColumn.*"
  6. creationComplete="Init()">
  7. <fx:Script>
  8. <![CDATA[
  9. import Common.YotuoUpload.CheckBoxColumn.CheckBoxHeaderRenderer;
  10. import Common.YotuoUpload.CheckBoxColumn.CheckBoxItemRenderer;
  11. import mx.collections.ArrayCollection;
  12.  
  13. public var dataArray:ArrayCollection = new ArrayCollection;
  14.  
  15. private function Init():void{
  16. dataArray.addItem({isSelected:false,name:'Christina Coenraets',phone:'555-219-2270',email:'ccoenraets@fictitious.com'});
  17. dataArray.addItem({isSelected:false,name:'Joanne Wall',phone:'555-219-2012',email:'jwall@fictitious.com'});
  18. dataArray.addItem({isSelected:false,name:'Maurice Smith',phone:'555-219-2012',email:'maurice@fictitious.com'});
  19. dataArray.addItem({isSelected:false,name:'Mary Jones',phone:'555-219-2000',email:'mjones@fictitious.com'});
  20. dataArray.addItem({isSelected:false,name:'God Win',phone:'555-219-2005',email:'godwin@fictitious.com'});
  21. dgUser.dataProvider = dataArray;
  22. }
  23. ]]>
  24. </fx:Script>
  25. <mx:DataGrid id="dgUser" x="10" y="10" width="450" height="200">
  26. <mx:columns>
  27. <CheckBoxColumn:CheckBoxColumn dataField="isSelected" width="25"
  28. draggable="false" resizable="false" sortable="false"
  29. headerRenderer="{new ClassFactory(CheckBoxHeaderRenderer)}"
  30. itemRenderer="{new ClassFactory(CheckBoxItemRenderer)}"
  31. />
  32. <mx:DataGridColumn headerText="姓名" dataField="name"/>
  33. <mx:DataGridColumn headerText="电话" dataField="phone"/>
  34. <mx:DataGridColumn headerText="邮件" dataField="email"/>
  35. </mx:columns>
  36. </mx:DataGrid>
  37. </s:Application>

2、通过代码动态调用:

 
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
  3. xmlns:s="library://ns.adobe.com/flex/spark"
  4. xmlns:mx="library://ns.adobe.com/flex/halo" minWidth="1024" minHeight="768"
  5. creationComplete="Init()">
  6. <fx:Script>
  7. <![CDATA[
  8. import mx.controls.dataGridClasses.DataGridColumn;
  9. import Common.YotuoUpload.CheckBoxColumn.CheckBoxColumn;
  10. import Common.YotuoUpload.CheckBoxColumn.CheckBoxHeaderRenderer;
  11. import Common.YotuoUpload.CheckBoxColumn.CheckBoxItemRenderer;
  12. import mx.collections.ArrayCollection;
  13.  
  14. public var dataArray:ArrayCollection = new ArrayCollection;
  15.  
  16. private function Init():void{
  17. dataArray.addItem({isSelected:false,name:'Christina Coenraets',phone:'555-219-2270',email:'ccoenraets@fictitious.com'});
  18. dataArray.addItem({isSelected:false,name:'Joanne Wall',phone:'555-219-2012',email:'jwall@fictitious.com'});
  19. dataArray.addItem({isSelected:false,name:'Maurice Smith',phone:'555-219-2012',email:'maurice@fictitious.com'});
  20. dataArray.addItem({isSelected:false,name:'Mary Jones',phone:'555-219-2000',email:'mjones@fictitious.com'});
  21. dataArray.addItem({isSelected:false,name:'God Win',phone:'555-219-2005',email:'godwin@fictitious.com'});
  22.  
  23. var _checkBoxCloumn:CheckBoxColumn = new CheckBoxColumn();
  24. _checkBoxCloumn.dataField = "isSelected";
  25. _checkBoxCloumn.headerRenderer = new ClassFactory(CheckBoxHeaderRenderer);
  26. _checkBoxCloumn.itemRenderer = new ClassFactory(CheckBoxItemRenderer);
  27. _checkBoxCloumn.width = 30;
  28. _checkBoxCloumn.sortable = false;
  29. _checkBoxCloumn.draggable = false;
  30.  
  31. var _nameColumn:DataGridColumn = new DataGridColumn();
  32. _nameColumn.headerText = "姓名";
  33. _nameColumn.dataField = "name";
  34.  
  35. var _telColumn:DataGridColumn = new DataGridColumn();
  36. _telColumn.headerText = "电话";
  37. _telColumn.dataField = "phone";
  38.  
  39. var _emailColumn:DataGridColumn = new DataGridColumn();
  40. _emailColumn.headerText = "邮件";
  41. _emailColumn.dataField = "email";
  42.  
  43. dgUser.columns = new Array(_checkBoxCloumn,_nameColumn,_telColumn,_emailColumn);
  44. dgUser.dataProvider = dataArray;
  45. }
  46. ]]>
  47. </fx:Script>
  48. <mx:DataGrid id="dgUser" x="10" y="10" width="450" height="200" />
  49. </s:Application>

PS:该组件要求在数据源中存在属性isSelected(Boolean类型,用来记录当前行是否被选中)属性,这样就限制了程序的通用性,试了很多方法都未很好解决,希望有办法解决的朋友给以指点。

示例运行效果:

p_w_picpath

本文作者: 宜城小子 发于: http://blog.yotuo.net(转载请保留此信息)
原文链接: http://blog.yotuo.net/post/2009/11/DataGrid-CheckBoxColumn.html