隨筆-193  評(píng)論-715  文章-1  trackbacks-0
          常常會(huì)用到帶有3種狀態(tài)CheckBox的樹(shù)形組件,比如在權(quán)限管理中,或者是地區(qū)選擇中等等,如下圖:


          不多說(shuō)費(fèi)話了,直接進(jìn)入主題,看看如何實(shí)現(xiàn)。其實(shí)在Flex中,只用自己實(shí)現(xiàn)一個(gè)TreeItemRenderer就可以了,代碼如下:
          package com.robin {
              import flash.events.Event;
              import flash.geom.Rectangle;
              
              import mx.controls.CheckBox;
              import mx.controls.treeClasses.TreeItemRenderer;
              import mx.controls.treeClasses.TreeListData;
              import mx.events.FlexEvent;

              public class ThreeStatusCheckBoxTreeItemRenderer extends TreeItemRenderer 
          {
                  private static 
          var _colorForThirdState:int = 0x37BEF8;
                  private static 
          var _selectedField:String = "selected";
                  
                  private 
          var checkBox:CheckBox;

                  public 
          function ThreeStatusCheckBoxTreeItemRenderer() {
                      super();
                  }


                  override protected 
          function createChildren():void {
                      super.createChildren();
                      checkBox 
          = new CheckBox();
                      addChild(checkBox);
                      checkBox.addEventListener(Event.CHANGE, changeHandler);
                  }


                  
          /**
                   * Initial data when component initialization
                   *
                   
          */

                  override protected 
          function commitProperties():void {
                      super.commitProperties();
                      
          if (data && data.@[_selectedField] != null{
                          
          var s:int = int(data.@[_selectedField]);
                          
          var selected:Boolean = s > 0 ? true : false;
                          checkBox.selected 
          = selected;
                      }
           else {
                          checkBox.selected 
          = false;
                      }

                  }


                  
          /**
                   * update dataProvider when user click CheckBox
                   *
                   
          */

                  protected 
          function changeHandler(event:Event):void {
                      
          if (data && data.@[_selectedField] != null{
                          data.@[_selectedField] 
          = checkBox.selected ? "1" : "0";
                      }

                      
                      
          var listData:TreeListData = TreeListData(listData);
                      
          if (listData.hasChildren) {
                          
          var item:XML = XML(listData.item);
                          handleAllChildren(item.children());
                      }

                      handleAllParents(listData.item.parent());
                  }


                  private 
          function handleAllChildren(children:XMLList):void {
                      
          for each (var item:XML in children) {
                          item.@[_selectedField] 
          = checkBox.selected ? "1" : "0";
                          
          var children:XMLList = item.children();
                          
          if (children.length() > 0{
                              handleAllChildren(children);
                          }

                      }

                  }


                  private 
          function handleAllParents(parent:XML):void {
                      
          if (parent != null{
                          
          var children:XMLList = parent.children();
                          
          var hasSelected1:Boolean = false;
                          
          var hasSelected2:Boolean = false;
                          
          var hasSelected0:Boolean = false;
                          
          for each (var item:XML in children) {
                              
          if (int(item.@[_selectedField]) == 1{
                                  hasSelected1 
          = true;
                              }

                              
          if (int(item.@[_selectedField]) == 2{
                                  hasSelected2 
          = true;
                              }

                              
          if (int(item.@[_selectedField]) == 0{
                                  hasSelected0 
          = true;
                              }

                          }

                          
          if (checkBox.selected == true{
                              
          if (!hasSelected0 && !hasSelected2) {
                                  parent.@[_selectedField] 
          = "1";
                              }
           else {
                                  parent.@[_selectedField] 
          = "2";
                              }

                          }
           else {
                              
          if (!hasSelected1 && !hasSelected2) {
                                  parent.@[_selectedField] 
          = "0";
                              }
           else {
                                  parent.@[_selectedField] 
          = "2";
                              }

                          }

                          handleAllParents(parent.parent());
                      }

                  }


                  
          /**
                   * reset itemRenderer's width
                   
          */

                  override protected 
          function measure():void {
                      super.measure();
                      measuredWidth 
          += checkBox.getExplicitOrMeasuredWidth();
                  }


                  
          /**
                   * re-assign layout for tree, move lable to right
                   * @param unscaledWidth
                   * @param unscaledHeight
                   
          */

                  override protected 
          function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void {
                      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();

                      
          var node:XML = data as XML;
                      
          if (int(node.@[_selectedField]) == 2{
                          fillCheckBox(
          true);
                      }
           else {
                          fillCheckBox(
          false);
                      }


                  }

                  
                  
          /**
                   * re-draw check box for the third state
                   * @param isFill
                   
          */

                  private 
          function fillCheckBox(isFill:Boolean):void {
                      checkBox.validateNow();
                      checkBox.graphics.clear();
                      
          if (isFill) {
                          
          var myRect:Rectangle = checkBox.getBounds(checkBox);
                          checkBox.graphics.beginFill(_colorForThirdState, 
          1);
                          checkBox.graphics.drawRoundRect(myRect.x, myRect.y, myRect.width, myRect.height, 
          10x00FF00);
                          checkBox.graphics.endFill();
                      }

                  }



              }

          }

          然后在tree組件中使用這個(gè)renderer就可以了。
          <?xml version="1.0" encoding="utf-8"?>
          <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
                         xmlns:s
          ="library://ns.adobe.com/flex/spark" 
                         xmlns:mx
          ="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600" xmlns:robin="com.robin.*">
              
          <fx:Declarations>
                  
          <fx:XMLList id="treeData">
                      
          <node name = "ShangHai" type="ROOT" selected ="1">
                          
          <node name = "HuangPu" type="NODE" selected = "1">
                              
          <node name = "A" type="NODE" selected = "1" />
                              
          <node name = "B" type="NODE" selected = "1" />
                          
          </node>
                          
          <node name = "PuDong" type="NODE" selected = "1"/>
                      
          </node>
                      
          <node name = "Beijing" type="ROOT" selected = "2">
                          
          <node name = "HaiDian" type="NODE" selected = "0"/>
                          
          <node name = "ChaoYang" type="NODE" selected = "1"/>
                      
          </node>
                  
          </fx:XMLList>
              
          </fx:Declarations>
              
          <fx:Script>
                  
          <![CDATA[
                      protected 
          function getCurrentData_clickHandler(event:MouseEvent):void {
                          currentText.text 
          = String(treeData);
                      }

                  ]]
          >
              
          </fx:Script>
              
              
          <mx:Tree x = "0" y = "0" width = "232" height = "285" itemRenderer = "com.robin.ThreeStatusCheckBoxTreeItemRenderer" labelField = "@name" dataProvider = "{treeData}"/>
              
          <s:Button x = "43" y = "293" label = "Get Current Data" id = "getCurrentData" click = "getCurrentData_clickHandler(event)"/>
              
          <s:TextArea x = "253" y = "0" width = "459" height = "285" id = "currentText"/>
          </s:Application>

          就是這么簡(jiǎn)單!
          posted on 2010-09-15 07:58 Robin's Programming World 閱讀(5949) 評(píng)論(7)  編輯  收藏 所屬分類: Flex & Flash

          評(píng)論:
          # re: Flex中帶有三種狀態(tài)CheckBox的Tree的實(shí)現(xiàn) 2011-09-21 11:21 | 729106109
          那后臺(tái)用java怎么組成所需要的tree呢?謝謝了  回復(fù)  更多評(píng)論
            
          # re: Flex中帶有三種狀態(tài)CheckBox的Tree的實(shí)現(xiàn) 2011-10-09 12:27 | Robin's Java World
          后臺(tái)什么數(shù)據(jù)結(jié)構(gòu)都無(wú)所謂,到前臺(tái)變成XML就可以了。  回復(fù)  更多評(píng)論
            
          # re: Flex中帶有三種狀態(tài)CheckBox的Tree的實(shí)現(xiàn)[未登錄](méi) 2011-12-09 09:22 | neil
          # re: Flex中帶有三種狀態(tài)CheckBox的Tree的實(shí)現(xiàn) 2012-01-05 14:16 | 歐巴
          在Java后臺(tái)拼成XML格式的字符串就可以了  回復(fù)  更多評(píng)論
            
          # re: Flex中帶有三種狀態(tài)CheckBox的Tree的實(shí)現(xiàn) 2013-04-27 17:21 | k-mart
          三個(gè)狀態(tài),很科學(xué),贊一個(gè)  回復(fù)  更多評(píng)論
            
          # re: Flex中帶有三種狀態(tài)CheckBox的Tree的實(shí)現(xiàn) 2015-07-21 10:23 | 鐘凡
          怎么去掉前面的小圖標(biāo)  回復(fù)  更多評(píng)論
            
          # re: Flex中帶有三種狀態(tài)CheckBox的Tree的實(shí)現(xiàn) 2016-01-04 17:39 | bns
          帶有3種狀態(tài)CheckBox的樹(shù)形組件剛好用到
          收了  回復(fù)  更多評(píng)論
            
          主站蜘蛛池模板: 咸宁市| 巨鹿县| 镶黄旗| 斗六市| 南乐县| 兴安县| 梁河县| 枣庄市| 丽水市| 莱阳市| 监利县| 剑川县| 霍城县| 大港区| 女性| 称多县| 大连市| 葫芦岛市| 余江县| 台中市| 红桥区| 镇康县| 饶平县| 霍山县| 林芝县| 谷城县| 宝清县| 措勤县| 垦利县| 丹巴县| 台安县| 岳阳市| 北京市| 遂昌县| 潮州市| 天峻县| 淮安市| 龙口市| 古田县| 通城县| 新泰市|