Flex CheckBox Tree 的两种方式

package com.easymap.components.render {     import com.easymap.components.CheckTree;      import flash.events.MouseEvent;   import flash.geom.Rectangle;   import flash.xml.*;      import mx.collections.*;   import mx.controls.CheckBox;   import mx.controls.Tree;   import mx.controls.listClasses.*;   import mx.controls.treeClasses.*;   import mx.events.FlexEvent;   import mx.events.ListEvent;

  /**    * 三状态复选框树控件    *  <br /><br />    */   public class CheckBoxTreeRenderer extends TreeItemRenderer   {    protected var myCheckBox:CheckBox;    /**     * STATE_SCHRODINGER : 部分子项选中 <br />     * STATE_CHECKED :     全部子项选中 <br />     * STATE_UNCHECKED :   全部子项未选中 <br />     */    static private var STATE_SCHRODINGER:int=2;    static private var STATE_CHECKED:int=1;    static private var STATE_UNCHECKED:int=0;    private var myTree:CheckTree;    public function CheckBoxTreeRenderer()    {     super();     mouseEnabled=true;    }    /**     * 初始化完成时处理复选框和图片对象     *     */    override protected function createChildren():void    {     myCheckBox=new CheckBox();     addChild(myCheckBox);     myCheckBox.addEventListener(MouseEvent.CLICK, checkBoxToggleHandler);          myTree = this.owner as CheckTree;          super.createChildren();          myTree.addEventListener(ListEvent.CHANGE,onPropertyChange);         }    protected function onPropertyChange(e:ListEvent=null):void    {     this.updateDisplayList(unscaledWidth,unscaledHeight);    }    /**     * // TODO : 递归设置父项目的状态     * @param item 项目     * @param tree 树对象     * @param state 目标状态     *     */    private function toggleParents(item:Object, tree:Tree, state:int):void    {     if (item == null)      return ;     else     {      var stateField:String=myTree.checkBoxStateField;      var tmpTree:IList=myTree.dataProvider as IList;      var oldValue:Number=item[stateField] as Number;      var newValue:Number=state as Number;            item[myTree.checkBoxStateField]=state;      tmpTree.itemUpdated(item,stateField,oldValue,newValue);            //item[myTree.checkBoxStateField]=state;      var parentItem:Object=tree.getParentItem(item);      if(null!=parentItem)       toggleParents(parentItem, tree, getState(tree, parentItem));     }    }    /**     * // TODO : 设置项目的状态和子项的状态     * @param item 项目     * @param tree 树对象     * @param state 目标状态     *     */    private function toggleChildren(item:Object, tree:Tree, state:int):void    {     if (item == null)      return ;     else     {      var stateField:String=myTree.checkBoxStateField;      var tmpTree:IList=myTree.dataProvider as IList;      var oldValue:Number=item[stateField] as Number;      var newValue:Number=state as Number;            item[myTree.checkBoxStateField]=state;      tmpTree.itemUpdated(item,stateField,oldValue,newValue);            var treeData:ITreeDataDescriptor=tree.dataDescriptor;      if (myTree.checkBoxCascadeOnCheck && treeData.hasChildren(item))      {       var children:ICollectionView=treeData.getChildren(item);       var cursor:IViewCursor=children.createCursor();       while(!cursor.afterLast)       {        toggleChildren(cursor.current, tree, state);        cursor.moveNext();       }      }     }    }    /**     * //TODO:获得parent的状态     * @param tree 树对象     * @param parent 目标项     * @return 状态     *     */    private function getState(tree:Tree, parent:Object):int    {     var noChecks:int=0;     var noCats:int=0;     var noUnChecks:int=0;     if (parent != null)     {      var treeData:ITreeDataDescriptor=tree.dataDescriptor;      var cursor:IViewCursor=treeData.getChildren(parent).createCursor();      while(!cursor.afterLast)      {       if (cursor.current[myTree.checkBoxStateField] == STATE_CHECKED)        noChecks++;       else if (cursor.current[myTree.checkBoxStateField] == STATE_UNCHECKED)        noUnChecks++;       else        noCats++;       cursor.moveNext();      }     }     if ((noChecks > 0 && noUnChecks > 0) || noCats > 0)      return STATE_SCHRODINGER;     else if (noChecks > 0)      return STATE_CHECKED;     else      return STATE_UNCHECKED;    }    /**     * //TODO:设置项目的父项状态和子项状态     * @param event 事件     *     */    private function checkBoxToggleHandler(event:MouseEvent):void    {     if (data)     {      var myListData:TreeListData=TreeListData(this.listData);      var selectedNode:Object=myListData.item;      myTree=myListData.owner as CheckTree;      var toggle:Boolean=myCheckBox.selected;      if (toggle)      {       toggleChildren(data, myTree, STATE_CHECKED);       if (myTree.checkBoxOpenItemsOnCheck)        myTree.expandChildrenOf(data, true);      }      else      {       toggleChildren(data, myTree, STATE_UNCHECKED);       if (myTree.checkBoxCloseItemsOnUnCheck)        myTree.expandChildrenOf(data, false);      }      //TODO:如果所有子项选中时需要选中父项则执行以下代码      if (myTree.checkBoxCascadeOnCheck)      {       var parent:Object=myTree.getParentItem(data);       if(null!=parent)        toggleParents(parent, myTree, getState(myTree, parent));      }     }     //myTree.PropertyChange();     //dispatchEvent(new FlexEvent(FlexEvent.DATA_CHANGE));    }    /**     * 设置本项的复选框状态     * @param checkBox 复选框     * @param value     * @param state 状态     *     */    private function setCheckState(checkBox:CheckBox, value:Object, state:int):void    {     if (state == STATE_CHECKED)      checkBox.selected=true;     else if (state == STATE_UNCHECKED)      checkBox.selected=false;     else if (state == STATE_SCHRODINGER)      checkBox.selected=false;    }    override public function set data(value:Object):void    {     if (value != null)     {      super.data=value;      setCheckState(myCheckBox, value, value[myTree.checkBoxStateField]);     }    }    override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void    {     super.updateDisplayList(unscaledWidth, unscaledHeight);     if (super.data)     {      if (super.icon != null)      {       myCheckBox.x=super.icon.x + myTree.checkBoxLeftGap;       myCheckBox.y=(height - myCheckBox.height) / 2;       super.icon.x=myCheckBox.x + myCheckBox.width + myTree.checkBoxRightGap;       super.label.x=super.icon.x + super.icon.width + 3;      }      else      {       myCheckBox.x=super.label.x + myTree.checkBoxLeftGap;       myCheckBox.y=(height - myCheckBox.height) / 2;       super.label.x=myCheckBox.x + myCheckBox.width + myTree.checkBoxRightGap;      }            setCheckState(myCheckBox, data, data[myTree.checkBoxStateField]);      if (myTree.checkBoxEnableState && data[myTree.checkBoxStateField] == STATE_SCHRODINGER)      {       fillCheckBox(true);       trace(myTree.checkBoxEnableState);       trace(data[myTree.checkBoxStateField]);      }      else       fillCheckBox(false);     }    }    protected function fillCheckBox(isFill:Boolean):void    {     myCheckBox.graphics.clear();     if (isFill)     {      var myRect:Rectangle=getCheckTreeBgRect(myTree.checkBoxBgPadding);      myCheckBox.graphics.beginFill(myTree.checkBoxBgColor, myTree.checkBoxBgAlpha)      myCheckBox.graphics.drawRoundRect(myRect.x, myRect.y, myRect.width, myRect.height, myTree.checkBoxBgElips, myTree.checkBoxBgElips);      myCheckBox.graphics.endFill();     }    }    protected function getCheckTreeBgRect(checkTreeBgPadding:Number):Rectangle    {     var myRect:Rectangle=myCheckBox.getBounds(myCheckBox);     myRect.top+=checkTreeBgPadding;     myRect.left+=checkTreeBgPadding;     myRect.bottom-=checkTreeBgPadding;     myRect.right-=checkTreeBgPadding;     return myRect;    }       } //end class

}

 

1.写一个渲染器

2.写一个Tree的子类

 

package com.easymap.components {   import com.easymap.components.render.CheckBoxTreeRenderer;   import com.easymap.components.render.CheckTreeRenderer;      import mx.controls.Tree;   import mx.core.ClassFactory;   import mx.events.ListEvent;

  /**    * 三状态复选框树控件    * <br /><br />    */      public class CheckTree extends Tree   {    //数据源中状态字段    private var m_checkBoxStateField:String="@state";    //部分选中的填充色    [Bindable]    private var m_checkBoxBgColor:uint=0x009900;    //填充色的透明度    [Bindable]    private var m_checkBoxBgAlpha:Number=1;    //填充色的边距    [Bindable]    private var m_checkBoxBgPadding:Number=3;    //填充色的四角弧度    [Bindable]    private var m_checkBoxBgElips:Number=2;    //取消选择是否收回子项    [Bindable]    private var m_checkBoxCloseItemsOnUnCheck:Boolean=true;    //选择项时是否展开子项    [Bindable]    private var m_checkBoxOpenItemsOnCheck:Boolean=false;    //选择框左边距的偏移量    [Bindable]    private var m_checkBoxLeftGap:int=8;    //选择框右边距的偏移量    [Bindable]    private var m_checkBoxRightGap:int=20;    //是否显示三状态    [Bindable]    private var m_checkBoxEnableState:Boolean=true;    //与父项子项关联    [Bindable]    private var m_checkBoxCascadeOnCheck:Boolean=true;        //双击项目    public var itemDClickSelect:Boolean=true;    public function CheckTree()    {     super();     doubleClickEnabled=true;    }    override protected function createChildren():void    {     var myFactory:ClassFactory=new ClassFactory(CheckBoxTreeRenderer);     this.itemRenderer=myFactory;     super.createChildren();     addEventListener(ListEvent.ITEM_DOUBLE_CLICK, onItemDClick);    }    public function PropertyChange():void    {     dispatchEvent(new ListEvent(mx.events.ListEvent.CHANGE));    }        /**     * 树菜单,双击事件     * @param evt 双击事件源     *     */    public function onItemDClick(e:ListEvent):void    {     if(itemDClickSelect)      OpenItems();    }    /**     * 打开Tree节点函数,被 有打开节点功能的函数调用     * @param item 要打开的节点     *     */    public function OpenItems():void    {     if (this.selectedIndex >= 0 && this.dataDescriptor.isBranch(this.selectedItem))      this.expandItem(this.selectedItem, !this.isItemOpen(this.selectedItem), true);    }        /**     * 数据源中状态字段     * @return     *     */      [Bindable]    public function get checkBoxStateField():String    {     return m_checkBoxStateField;    }    public function set checkBoxStateField(v:String):void    {     m_checkBoxStateField=v;     PropertyChange();    }        /**     * 部分选中的填充色     * @return     *     */      [Bindable]    public function get checkBoxBgColor():uint    {     return m_checkBoxBgColor;    }    public function set checkBoxBgColor(v:uint):void    {     m_checkBoxBgColor=v;     PropertyChange();    }        /**     * 填充色的透明度     * @return     *     */      [Bindable]    public function get checkBoxBgAlpha():Number    {     return m_checkBoxBgAlpha;    }    public function set checkBoxBgAlpha(v:Number):void    {     m_checkBoxBgAlpha=v;     PropertyChange();    }            /**     * 填充色的边距     * @return     *     */      [Bindable]    public function get checkBoxBgPadding():Number    {     return m_checkBoxBgPadding;    }    public function set checkBoxBgPadding(v:Number):void    {     m_checkBoxBgPadding=v;     PropertyChange();    }        /**     * 填充色的四角弧度     * @return     *     */      [Bindable]    public function get checkBoxBgElips():Number    {     return m_checkBoxBgElips;    }    public function set checkBoxBgElips(v:Number):void    {     m_checkBoxBgElips=v;     PropertyChange();    }            /**     * 取消选择是否收回子项     * @return     *     */      [Bindable]    public function get checkBoxCloseItemsOnUnCheck():Boolean    {     return m_checkBoxCloseItemsOnUnCheck;    }    public function set checkBoxCloseItemsOnUnCheck(v:Boolean):void    {     m_checkBoxCloseItemsOnUnCheck=v;     PropertyChange();    }            /**     * 选择项时是否展开子项     * @return     *     */      [Bindable]    public function get checkBoxOpenItemsOnCheck():Boolean    {     return m_checkBoxOpenItemsOnCheck;    }    public function set checkBoxOpenItemsOnCheck(v:Boolean):void    {     m_checkBoxOpenItemsOnCheck=v;     PropertyChange();    }            /**     * 选择框左边距的偏移量     * @return     *     */      [Bindable]    public function get checkBoxLeftGap():int    {     return m_checkBoxLeftGap;    }    public function set checkBoxLeftGap(v:int):void    {     m_checkBoxLeftGap=v;     PropertyChange();    }            /**     * 选择框右边距的偏移量     * @return     *     */      [Bindable]    public function get checkBoxRightGap():int    {     return m_checkBoxRightGap;    }    public function set checkBoxRightGap(v:int):void    {     m_checkBoxRightGap=v;     PropertyChange();    }            /**     * 是否显示三状态     * @return     *     */      [Bindable]    public function get checkBoxEnableState():Boolean    {     return m_checkBoxEnableState;    }    public function set checkBoxEnableState(v:Boolean):void    {     m_checkBoxEnableState=v;     PropertyChange();    }                /**     * 与父项子项关联     * @return     *     */    [Bindable]    public function get checkBoxCascadeOnCheck():Boolean    {     return m_checkBoxCascadeOnCheck;    }    public function set checkBoxCascadeOnCheck(v:Boolean):void    {     m_checkBoxCascadeOnCheck=v;     PropertyChange();    }       }  

}

 

效果:

flex CheckBox Tree 的两种方式 - sejin - 夏之雪之家
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值