Flex CheckBox Tree 的两种方式

来源:互联网 发布:js 数组排序函数 编辑:程序博客网 时间:2024/06/05 09:40

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
原创粉丝点击