CheckBoxTree

来源:互联网 发布:c语言成绩管理系统思路 编辑:程序博客网 时间:2024/06/06 01:34

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
    fontSize="12"
    xmlns:controls="ht.*"
    creationComplete="initApp()"
    layout="horizontal">
 <mx:Script>
  <![CDATA[
     import mx.collections.*;
    import ht.*;
    import mx.collections.ArrayCollection;
    [Bindable]
    public var arrarc:ArrayCollection=new ArrayCollection([
    {state:0,label:"有效值"},
    {state:0,label:"平均值"},
    {state:0,label:"峰值"},
    {state:0,label:"峰峰值"},
    {state:0,label:"X1"},
    {state:2,label:"频带",
    children:[
    {state:0, label:"频带1"},
    {state:1, label:"频带2"},
    {state:0, label:"频带3"},
    {state:0, label:"频带4"},
    {state:0, label:"频带5"},
    ]
    }
    ]);
    [Bindable]
    public var folderList:XMLList=
    <>
    <folder state="0" label="Marketing Collateral">
    <folder state="0" label="Media,PR,and Communications" >
    <folder state="0" label="Article Reprint Disclaimers" />
    <folder state="0" label="Articles Reprints" />
    <folder state="0" label="Interviews and Transcripts" />
    <folder state="0" label="Press Kits" />
    <folder state="0" label="Press Releases" />
    <folder state="0" label="Quick Hits" />
    <folder state="0" label="Rep Talking Points" />
    <folder state="0" label="Special Updates" />
    <folder state="0" label="White Papers" />
    </folder>
    <folder state="0" label="Forms and Applications" >
    <folder state="0" label="Applications" />
    <folder state="0" label="Forms" />
    </folder>
    </folder>
    </>
    ;
    [Bindable]
    public var folderCollection:XMLListCollection;
    override protected function initializationComplete():void
    {
    super.initializationComplete();
    folderCollection=new XMLListCollection(folderList);
    }
    protected function initApp():void
    {
    this.callLater(test);
    }
    protected function test():void
    {
    tree3.checkBoxOpenItemsOnCheck=true;
    tree3.checkBoxCascadeOnCheck=true;
    tree3.checkBoxEnableState=false;
    tree3.itemDClickSelect=true;

    tree2.checkBoxOpenItemsOnCheck=true;
    tree2.checkBoxCascadeOnCheck=true;
    tree2.checkBoxEnableState=true;
    tree2.checkBoxBgColor=0x000000;
    }
    ]]>
 </mx:Script>
 <mx:Panel width="166"
     height="100%"
     layout="absolute">
  <mx:Form x="0"
     y="0"
     width="146"
     height="100%">
   <mx:CheckBox label="取消收回子项"
       id="checkBoxCloseItemsOnUnCheck"
       selected="true"/>
   <mx:CheckBox label="选中展开子项"
       id="checkBoxOpenItemsOnCheck"/>
   <mx:CheckBox label="是否三状态"
       id="checkBoxEnableState"
       selected="true"/>
   <mx:CheckBox label="是否关联父子"
       id="checkBoxCascadeOnCheck"
       selected="true"/>
   <mx:FormItem label="样式"
       direction="vertical">
    <mx:ColorPicker id="checkBoxBgColor"
        selectedColor="#009900"/>
    <mx:HSlider width="61"
       id="checkBoxBgAlpha"
       allowTrackClick="true"
       minimum="0"
       maximum="1"
       snapInterval="0.1"
       value="1"/>
   </mx:FormItem>
   <mx:FormItem label="填充边距">
    <mx:NumericStepper id="checkBoxBgPadding"
           value="3"
           minimum="0"
           maximum="6"
           stepSize="1"/>
   </mx:FormItem>
   <mx:FormItem label="填充弧度">
    <mx:NumericStepper id="checkBoxBgElips"
           value="2"
           minimum="0"
           maximum="6"
           stepSize="1"/>
   </mx:FormItem>
   <mx:FormItem label="左边距">
    <mx:NumericStepper id="checkBoxLeftGap"
           value="8"
           minimum="0"
           maximum="20"
           stepSize="1"/>
   </mx:FormItem>
   <mx:FormItem label="右边距">
    <mx:NumericStepper id="checkBoxRightGap"
           value="20"
           minimum="0"
           maximum="40"
           stepSize="1"/>
   </mx:FormItem>
   <mx:CheckBox label="双击是否展开项"
       id="itemDClickSelect"
       selected="true"/>
  </mx:Form>
  <mx:ControlBar height="46"
        y="321">
   <mx:ToggleButtonBar>

    <mx:dataProvider>
     <mx:Array>
      <mx:String>Flash</mx:String>
      <mx:String>Director</mx:String>
      <mx:String>Dreamweaver</mx:String>
      <mx:String>ColdFusion</mx:String>
     </mx:Array>
    </mx:dataProvider>
   </mx:ToggleButtonBar>
  </mx:ControlBar>
 </mx:Panel>

 <controls:CheckTree id="tree1"
      checkBoxStateField="@state"
      labelField="@label"
      dataProvider="{folderCollection}"
      width="100%"
      height="100%"
      checkBoxCloseItemsOnUnCheck="{checkBoxCloseItemsOnUnCheck.selected}"
      checkBoxOpenItemsOnCheck="{checkBoxOpenItemsOnCheck.selected}"
      checkBoxEnableState="{checkBoxEnableState.selected}"
      checkBoxCascadeOnCheck="{checkBoxCascadeOnCheck.selected}"
      checkBoxBgColor="{checkBoxBgColor.selectedColor}"
      checkBoxBgAlpha="{checkBoxBgAlpha.value}"
      checkBoxBgPadding="{checkBoxBgPadding.value}"
      checkBoxBgElips="{checkBoxBgElips.value}"
      checkBoxLeftGap="{checkBoxLeftGap.value}"
      checkBoxRightGap="{checkBoxRightGap.value}"
      itemDClickSelect="{itemDClickSelect.selected}"/>
 <controls:CheckTree id="tree2"
      width="100%"
      labelField="label"
      checkBoxStateField="state"
      dataProvider="{arrarc}"
      height="100%"/>
 <controls:CheckTree id="tree3"
      width="100%"
      labelField="label"
      checkBoxStateField="state"
      dataProvider="{arrarc}"
      height="100%"/>
</mx:Application>

/*************************************************
 ****
 **** 黄记新,2010-12-14,下午02:56:35
 ****
 ************************************************/

package ht
{
 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(CheckTreeRenderer);
   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();
  }

 }
}

/*************************************************
 ****  
 **** 黄记新,2010-12-14,下午02:57:52
 ****
 ************************************************/

package ht
{
 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 CheckTreeRenderer 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 CheckTreeRenderer() 
  { 
   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 
}

原创粉丝点击