项目中菜单树+复选框的需求,以为像平常的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测试即可。
另附一张效果图: