项目中菜单树+复选框的需求,以为像平常的list控件加个itemrender就可以搞定,谁知道不是那么回事。果断baidu。看到有大神写过,果断看tree的源码,发现:
tree在构造函数中已经默认设置了一个itemrnederer。而且它的itemrenderer和其它的不太一样,包含三个部分:1. 打开/关闭按钮 2. 文件夹图标 3.文本框
解决方案:
复写tree的itemrender,源码如下:
package com.csms.view.renderers.design
{
import com.csms.model.vo.DrawingtypeVo;
import flash.events.Event;
import mx.binding.utils.BindingUtils;
import mx.collections.ArrayCollection;
import mx.controls.CheckBox;
import mx.controls.Tree;
import mx.controls.treeClasses.TreeItemRenderer;
import mx.controls.treeClasses.TreeListData;
public class TreeCheckBoxRenderer extends TreeItemRenderer
{
public function TreeCheckBoxRenderer()
{
super();
}
private var _selectedField:String = "selected";
protected var checkBox:CheckBox;
override protected function createChildren():void
{
super.createChildren();
if(!checkBox){
checkBox = new CheckBox();
addChild( checkBox );
checkBox.addEventListener(Event.CHANGE, changeHandler);
}
}
/**
* 复选框变化事件,绑定子级
* */
protected function changeHandler( event:Event ):void
{
trace(checkBox.selected);
if( data && data[_selectedField] != undefined )
{
data[_selectedField] = checkBox.selected;
trace("data[_selectedField]" + checkBox.selected);
bindChilren(data as DrawingtypeVo);
}
}
/**
* 复选框变化,改变数据源后,调用此方法,绑定父级
* */
override protected function commitProperties():void
{
trace("commitProperties");
super.commitProperties();
if( data && data[_selectedField] != undefined )
{
bindFather(data as DrawingtypeVo);
checkBox.selected = data[_selectedField];
}
else
{
trace("checkBox.selected =" + checkBox.selected);
checkBox.selected = false;
}
}
/**
* 测量尺寸
* */
override protected function measure():void
{
super.measure();
measuredWidth += checkBox.getExplicitOrMeasuredWidth();
}
/**
* 更新显示列表
* */
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
{
trace("updateDisplayList");
super.updateDisplayList(unscaledWidth, unscaledHeight);
var startx:Number = data ? TreeListData( listData ).indent : 0;
//关闭/打开图标显示位置
if (disclosureIcon)
{
disclosureIcon.x = startx;
startx = disclosureIcon.x + disclosureIcon.width;
disclosureIcon.setActualSize(disclosureIcon.width,
disclosureIcon.height);
disclosureIcon.visible = data ?
TreeListData( listData ).hasChildren :
false;
}
//文件夹图标显示位置
if (icon)
{
icon.x = startx;
startx = icon.x + icon.measuredWidth;
icon.setActualSize(icon.measuredWidth, icon.measuredHeight);
}
//移动复选框到文件夹图标后
checkBox.move(startx, ( unscaledHeight - checkBox.height ) / 2 );
//将显示文本设置到复选框后
label.x = startx + checkBox.getExplicitOrMeasuredWidth();
}
/**
* 绑定父级:如果子级有选中的,父级选中;如果没有选中的父级不选中
* */
private function bindFather(drawingtype:DrawingtypeVo):void{
trace("bindFather:" + drawingtype.FName);
var childType:ArrayCollection = drawingtype.children;
var ischeck:Boolean = false;
if(childType != null && childType.length > 0){
for (var i:int = 0; i < childType.length; i++)
{
var currtype:DrawingtypeVo = childType[i] as DrawingtypeVo;
if(currtype.selected){
ischeck = true;
break;
}
}
drawingtype.selected = ischeck;
}
trace("bindFather:" + drawingtype.FName + ":" + ischeck);
}
/**
* 绑定子级: 如果父级选中,子级全选; 如果父级未选中,子级全不选
* */
private function bindChilren(drawingtype:DrawingtypeVo):void{
trace(drawingtype.FName);
drawingtype.selected = (data as DrawingtypeVo).selected;
var childType:ArrayCollection = drawingtype.children;
if(childType != null && childType.length > 0){
for (var i:int = 0; i < childType.length; i++)
{
var currtype:DrawingtypeVo = childType[i] as DrawingtypeVo;
bindChilren(currtype);
}
}
}
}
}
实体类:
package com.csms.model.vo
{
import mx.collections.ArrayCollection;
[Bindable]
[RemoteClass(alias="com.csms.model.vo.DrawingtypeVo")]
/**
*
* @author fengmoyan
*
*/
public class DrawingtypeVo
{
private var _FId:String;
private var _drawingtype:DrawingtypeVo;
private var _FName:String;
private var _FIndex:String;
private var _FMark:String;
private var _drawings:Array;
private var _partprojectDrawingtypes:Array;
private var _drawingtypes:Array;
private var _FParentId:String;
private var _selected:Boolean;
private var _children:ArrayCollection;
public function DrawingtypeVo()
{
}
public function get selected():Boolean
{
return _selected;
}
public function set selected(value:Boolean):void
{
_selected = value;
}
public function get children():ArrayCollection
{
return _children;
}
public function set children(value:ArrayCollection):void
{
_children = value;
}
public function get FParentId():String
{
return _FParentId;
}
public function set FParentId(value:String):void
{
_FParentId = value;
}
public function get FId():String
{
return _FId;
}
public function set FId(value:String):void
{
_FId = value;
}
public function get drawingtype():DrawingtypeVo
{
return _drawingtype;
}
public function set drawingtype(value:DrawingtypeVo):void
{
_drawingtype = value;
}
public function get FName():String
{
return _FName;
}
public function set FName(value:String):void
{
_FName = value;
}
public function get FIndex():String
{
return _FIndex;
}
public function set FIndex(value:String):void
{
_FIndex = value;
}
public function get FMark():String
{
return _FMark;
}
public function set FMark(value:String):void
{
_FMark = value;
}
public function get drawings():Array
{
return _drawings;
}
public function set drawings(value:Array):void
{
_drawings = value;
}
public function get partprojectDrawingtypes():Array
{
return _partprojectDrawingtypes;
}
public function set partprojectDrawingtypes(value:Array):void
{
_partprojectDrawingtypes = value;
}
public function get drawingtypes():Array
{
return _drawingtypes;
}
public function set drawingtypes(value:Array):void
{
_drawingtypes = value;
}
}
}
使用时在页面上引用即可
<mx:Tree height="100%" id="tree" allowMultipleSelection="true" itemRenderer="com.csms.view.renderers.design.TreeCheckBoxRenderer" width="60%" dataProvider="{_targetData}" labelField="FName" ></mx:Tree>
功能简介:
1. 添加了复选框
2. 父级和子级级联
a> 点击父级时,全选/全不选子级
b> 点击子级时,同一级如果有选中的则选中父级,反之不选中父级
备注:
1. 重写tree的项显示器
2.添加checkbox
3.给checkbox添加事件
4.当checkbox状态改变时改变数据源选中状态,并绑定子级选中状态
5.改变后复写父类的commitproperties方法(此方法会在属性改变时调用),绑定父级的选中状态
6.父写父级updatedisplay方法(此方法在组件渲染时调用),设置树形菜单视图
因项目需要,所以树形菜单是从数据库中读取的,如果有需要该功能的,可以自定义一个静态的arraycolloction测试即可。
另附一张效果图:
![](http://hi.csdn.net/attachment/201112/20/0_1324367331BotM.gif)