隨筆-193  評論-715  文章-1  trackbacks-0
          常常會用到帶有3種狀態CheckBox的樹形組件,比如在權限管理中,或者是地區選擇中等等,如下圖:


          不多說費話了,直接進入主題,看看如何實現。其實在Flex中,只用自己實現一個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組件中使用這個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>

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

          評論:
          # re: Flex中帶有三種狀態CheckBox的Tree的實現 2011-09-21 11:21 | 729106109
          那后臺用java怎么組成所需要的tree呢?謝謝了  回復  更多評論
            
          # re: Flex中帶有三種狀態CheckBox的Tree的實現 2011-10-09 12:27 | Robin's Java World
          后臺什么數據結構都無所謂,到前臺變成XML就可以了。  回復  更多評論
            
          # re: Flex中帶有三種狀態CheckBox的Tree的實現[未登錄] 2011-12-09 09:22 | neil
          不行  回復  更多評論
            
          # re: Flex中帶有三種狀態CheckBox的Tree的實現 2012-01-05 14:16 | 歐巴
          在Java后臺拼成XML格式的字符串就可以了  回復  更多評論
            
          # re: Flex中帶有三種狀態CheckBox的Tree的實現 2013-04-27 17:21 | k-mart
          三個狀態,很科學,贊一個  回復  更多評論
            
          # re: Flex中帶有三種狀態CheckBox的Tree的實現 2015-07-21 10:23 | 鐘凡
          怎么去掉前面的小圖標  回復  更多評論
            
          # re: Flex中帶有三種狀態CheckBox的Tree的實現 2016-01-04 17:39 | bns
          帶有3種狀態CheckBox的樹形組件剛好用到
          收了  回復  更多評論
            
          主站蜘蛛池模板: 本溪市| 红桥区| 长春市| 宁波市| 萨嘎县| 绥芬河市| 英山县| 柳林县| 孟村| 涞水县| 阜城县| 理塘县| 美姑县| 留坝县| 东乡| 游戏| 通州市| 甘南县| 通辽市| 兴仁县| 望城县| 铜陵市| 深泽县| 金阳县| 新郑市| 乌拉特前旗| 当雄县| 洛南县| 浦城县| 乌兰察布市| 河北省| 安陆市| 安吉县| 射洪县| 普兰店市| 宜都市| 石楼县| 上杭县| 浠水县| 宁阳县| 沁阳市|