为Flex Datagrid添加复选框列

如果设置MX DataGrid的allowMultipleSelection值为true,就可以结合使用Ctrl或Alt选择多个项目。但是很多用户并不知道这样操作,他们更习惯通过复选框进行选择,因此我们有必要为DataGrid添加复选框列。通过列标题的复选框项渲染器可以全选或全部取消选择。

我们将headerRenderer和itemRenderer都设定为MXDataGridItemRenderer,将复选框放置在该容器中。当然也可以直接将他们设定为复选框,但这样做意味着只能使用MX版的复选框,使用不了Flex中的Skin新特性。

MXDataGridItemRenderer的owner属性将得到DataGrid本身。列标题的复选框项渲染器的实现比较复杂,它与DataGrid是相互作用的。当复选框改变状态时,我们通过监听复选框的Change事件处理函数来设定DataGrid为全选、全部取消。另一方面,通过监听DataGrid的Change和valueCommit事件以及DataGrid数据提供者的collectionChange事件,对比其数据提供者的长度和其当前选项的长度,来判断列标题的复选框的状态是全选、全部取消还是部分选择。如下面代码片段:

private function init():void
{
  var grid:ListBase= owner as ListBase;
  grid.addEventListener(ListEvent.CHANGE, changeHandler);
  grid.addEventListener(FlexEvent.VALUE_COMMIT, changeHandler);
  IList(grid.dataProvider).addEventListener(CollectionEvent.COLLECTION_CHANGE, changeHandler);
  
}

private function changeHandler(event:Event):void
{
  var grid:ListBase= owner as ListBase;
  var items:Array = grid.selectedItems;
  var count:int = items ? items.length : 0;
  var len:int = grid.dataProvider.length;
  cb.selected = count > 0 && len == count;
  cb.enabled = count >= 0 && len > 0;
  cb.partial = count > 0;
  grid.enabled = len > 0;
}

针对列标题的复选框渲染器,我们为其新增了部分选择时的状态和皮肤。详见TriStateCheckBoxSkin.mxml。

另外,我们在DataGrid自定义类中覆写了set columns方法,始终设置第一列为复选框列。同时还覆写了keyDownHandler事件处理函数和selectItem方法以确保不使用功能键也能多选。

点击此处查看该实例最终效果,点击此处下载该实例的源码。

同样我们也可以为AdvancedDataGrid添加复选框列,只需要将MXDataGridItemRenderer改为MXAdvancedDataGridItemRenderer,其owner为AdvancedDataGrid本身。点击此处下载该实例的源码。

发表评论