现在的位置: 首页 > 综合 > 正文

Flex3 带复选框的树状下拉框

2014年09月05日 ⁄ 综合 ⁄ 共 7735字 ⁄ 字号 评论关闭

Main.mxml主程序文件:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" xmlns:component="component.*">
        <mx:Script>
                <![CDATA[
                        import mx.collections.ArrayCollection;
                        
                        [Bindable]
                        public var gridDataProvider:ArrayCollection = new ArrayCollection;
                        
                        /**
                         * 获取选中项
                         */
                        public function selectedItemChangeHandler():void
                        {
                                var result:Array;
                                if (treeComboBox.treeSelectedItems.length)
                                {
                                        result = treeComboBox.treeSelectedItems;
                                }
                                else
                                {
                                        result = [treeComboBox.treeSelectedItem];
                                }
                                gridDataProvider.source = result;
                        }
                ]]>
        </mx:Script>
        
        <mx:XMLList id="dataProvider"> 
                <node label="label-1" value="label-1-value"> 
                        <node label="label-1_1" value="label-1-value" /> 
                        <node label="label-1_2" value="label-1-value" /> 
                        <node label="label-1_3" value="label-1-value" /> 
                </node> 
                <node label="label-2" value="label-1-value" > 
                        <node label="label-2_1" value="label-1-value" /> 
                        <node label="label-2_2" value="label-1-value" /> 
                        <node label="label-2_3" value="label-1-value" /> 
                </node> 
                <node label="label-3" value="label-1-value" /> 
        </mx:XMLList> 
        
        <mx:CheckBox x="50" y="20" id="checkBox" label="只选子节点" selected="false" />
        
        <component:TreeComboBox id="treeComboBox"
                x="50" y="50"
                dataProvider="{dataProvider}"  
                labelField="@label"  
                treeHeight="150" 
                width="200" 
                isParentSelectable="{!checkBox.selected}"
                close="{selectedItemChangeHandler()}"
                />
        
        <mx:Label x="50" y="80" text="选中的项目:" fontWeight="bold" />
        
        <mx:DataGrid x="50" y="100"
                dataProvider="{gridDataProvider}" >
                <mx:columns>
                        <mx:DataGridColumn headerText="Label" dataField="@label" />
                        <mx:DataGridColumn headerText="Value" dataField="@value" />
                </mx:columns>
        </mx:DataGrid>
</mx:Application>

TreeComboBox.as文件:

package component 
{ 
        import mx.controls.ComboBox;
        import mx.core.ClassFactory;
        import mx.events.DropdownEvent;
        import mx.events.ListEvent; 
        
        [Event(name="treeChange", type="mx.events.ListEvent")] 
        
        public class TreeComboBox extends ComboBox 
        { 
                private var _ddFactory:ClassFactory; 
                
                /**
                 * 设置项目渲染器 
                 */                
                private function get ddFactory():ClassFactory 
                { 
                        if (_ddFactory == null) 
                        { 
                                _ddFactory = new ClassFactory(); 
                                _ddFactory.generator = TreeComboBoxRenderer; 
                                _ddFactory.properties = { 
                                        width:this.width,  
                                        height:this._treeHeight, 
                                        outerDocument:this 
                                }; 
                        } 
                        return _ddFactory;       
                }    
                
                /**
                 * 下拉树的高度 
                 */                
                private var _treeHeight:Number; 
                public function get treeHeight():Number 
                { 
                        return _treeHeight; 
                } 
                public function set treeHeight(value:Number):void 
                { 
                        this._treeHeight = value; 
                        ddFactory.properties["height"] = this._treeHeight; 
                }
                
                /**
                 * 设定是否可以选择父级结点 
                 */                
                private var _isParentSelectable:Boolean = true; 
                [Inspectable(enumeration="true,false", defaultValue="true")] 
                public function set isParentSelectable(value:Boolean):void 
                { 
                        _isParentSelectable = value; 
                }
                public function get isParentSelectable():Boolean
                {
                        return _isParentSelectable;
                }
                
                /**
                 * 选中项 
                 */                
                private var _treeSelectedItem:Object; 
                public function set treeSelectedItem(item:Object):void 
                { 
                        _treeSelectedItem = item; 
                        if (!_treeSelectedItem)  
                        { 
                                selectedIndex = -1; 
                                text = null; 
                        } 
                        dispatchEvent(new ListEvent("treeChange")); 
                } 
                [Bindable(event="treeChange")] 
                public function get treeSelectedItem():Object 
                { 
                        return _treeSelectedItem; 
                }
                
                /**
                 * 选中项的数组(通过CheckBox选择的项目) 
                 */                
                private var _treeSelectedItems:Array = [];
                public function set treeSelectedItems(array:Array):void
                {
                        if (array)
                        {
                                _treeSelectedItems = array;
                                dispatchEvent(new ListEvent("treeChange")); 
                        }
                }
                public function get treeSelectedItems():Array
                {
                        return _treeSelectedItems;
                }
                
                public function TreeComboBox() 
                { 
                        super(); 
                        
                        this.dropdownFactory = ddFactory; 
                        
                        this.addEventListener(DropdownEvent.OPEN, onComboOpen); 
                        
                        selectedIndex = -1; 
                } 
                
                /**
                 * 展开下拉树 
                 */                
                private function onComboOpen(event:DropdownEvent):void 
                { 
                        var tree:TreeComboBoxRenderer = dropdown as TreeComboBoxRenderer; 
                        
                        if (treeSelectedItem) 
                        { 
                                tree.expandParents(treeSelectedItem); 
                                tree.selectNode(treeSelectedItem); 
                        } 
                        else 
                        { 
                                try{ 
                                        if (dataProvider[0]) 
                                        { 
                                                tree.expandItem(dataProvider.getItemAt(0), true); 
                                        } 
                                }catch(e:Error) 
                                { 
                                } 
                        } 
                } 
                
                /** 
                 * private
                 */ 
                override protected function updateDisplayList(unscaledWidth:Number,  
                        unscaledHeight:Number):void  
                {  
                        super.updateDisplayList(unscaledWidth, unscaledHeight);    
                        
                        if(dropdown && treeSelectedItem && treeSelectedItem[labelField] != null) 
                        {    
                                text = treeSelectedItem[labelField];  
                        } 
                }  
                
                /**
                 * 是否可选
                 */                
                public function isSelectable(data:Object):Boolean 
                { 
                        return (_isParentSelectable || (data.children().length() <= 0)); 
                } 
                
                /**
                 * 更新选中项 
                 */                
                public function updateLabel(selectedItem:Object):void 
                { 
                        if (selectedItem) 
                        { 
                                treeSelectedItem = selectedItem; 
                        } 
                } 
        } 
} 

TreeComboBoxRenderer.as文件:

package component 
{ 
        import mx.controls.Tree;
        import mx.core.ClassFactory;
        import mx.events.ListEvent;
        
        /**
         * 
         * @author zhangzhicheng
         * 
         */        
        public class TreeComboBoxRenderer extends Tree 
        { 
                
                [Bindable] 
                public var outerDocument:TreeComboBox; 
                
                public function TreeComboBoxRenderer() 
                { 
                        super(); 
                        this.itemRenderer = new ClassFactory(CheckBoxTreeRenderer);
                        this.addEventListener(ListEvent.CHANGE, onSelectionChanged); 
                        this.setStyle("defaultLeafIcon", null); 
                        this.setStyle("folderClosedIcon", null); 
                        this.setStyle("folderOpenIcon", null); 
                } 
                
                /**
                 * 选中项目更改
                 */                
                private function onSelectionChanged(event:ListEvent):void 
                { 
                        outerDocument.updateLabel(event.currentTarget.selectedItem); 
                } 
                
                /**
                 * 打开父结点
                 */                
                public function expandParents(node:Object):void 
                { 
                        if (node && !isItemOpen(node)) 
                        { 
                                expandItem(node, true); 
                                expandParents(node.parent()); 
                        }        
                } 
                
                /**
                 * 设置选中节点 
                 */                
                public function selectNode(node:Object):void 
                { 
                        selectedItem = node; 
                        var idx:int = getItemIndex(selectedItem); 
                        scrollToIndex(idx); 
                } 
                
                /**
                 * 是否可以选择
                 */                
                override public function isItemSelectable(data:Object):Boolean 
                { 
                        return  super.isItemSelectable(data) && outerDocument.isSelectable(data); 
                } 
                
                /**
                 * 更新选中项目的数组
                 */                
                public function updateSelectedItems(data:Object, select:Boolean):void
                {
                        if (select) 
                        {
                                treeSelectedItems.push(data);
                        }
                        else
                        {
                                treeSelectedItems.splice(treeSelectedItems.indexOf(data), 1);
                        }
                }
                
                /**
                 * 选中项目数组
                 */                
                public function get treeSelectedItems():Array
                {
                        return outerDocument.treeSelectedItems;
                }
                
        } 
}
CheckBoxTreeRenderer.as文件:
package component
{
        import flash.events.MouseEvent;
        
        import mx.controls.CheckBox;
        import mx.controls.treeClasses.TreeItemRenderer;
        import mx.controls.treeClasses.TreeListData;
        
        /**
         * 
         * @author zhangzhicheng
         * 
         */        
        public class CheckBoxTreeRenderer extends TreeItemRenderer
        {
                private var _checkBox:CheckBox;
                
                public function CheckBoxTreeRenderer()
                {
                        super();
                }
                
                /**
                 *  @private
                 */
                override protected function createChildren():void
                {
                        super.createChildren();
                        
                        if (!_checkBox) 
                        {
                                _checkBox = new CheckBox;
                        }
                        
                        _checkBox.addEventListener(MouseEvent.MOUSE_DOWN, checkBoxMouseDownHandler);
                        _checkBox.addEventListener(MouseEvent.CLICK, checkBoxClickHandler);
                        
                        addChild(_checkBox);
                }
                
                /**
                 *  @private
                 */
                override protected function measure():void
                {
                        super.measure();
                        
                        if (isNaN(explicitWidth))
                        {
                                 
                                measuredWidth += _checkBox.width + 4;
                                measuredHeight = label.getExplicitOrMeasuredHeight();
                        }
                        else
                        {
                                if (_checkBox.measuredHeight > measuredHeight) 
                                        measuredHeight = _checkBox.measuredHeight;
                        }
                }
                
                /**
                 *  @private
                 */                
                override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
                {
                        super.updateDisplayList(unscaledWidth, unscaledHeight);
                        
                        var treeData:TreeListData = (listData as TreeListData);
                        var startx:Number =  treeData ? treeData.indent : 0;
                        
                        if (disclosureIcon)
                        {
                                disclosureIcon.x = startx;
                                
                                startx = disclosureIcon.x + disclosureIcon.width;
                                
                                disclosureIcon.setActualSize(disclosureIcon.measuredWidth,
                                        disclosureIcon.measuredHeight);
                                
                                disclosureIcon.visible = data ?
                                        treeData.hasChildren :
                                        false;
                        }
                        
                        if (icon)
                        {
                                icon.x = startx;
                                startx = icon.x + icon.measuredWidth;
                                icon.setActualSize(icon.measuredWidth, icon.measuredHeight);
                        }
                        
                        if (_checkBox)
                        {
                                _checkBox.x = startx + 2;
                                
                                startx = _checkBox.x + _checkBox.measuredWidth + 2;
                                
                                _checkBox.setActualSize(_checkBox.measuredWidth, _checkBox.measuredHeight);
                                
                                _checkBox.selected = (owner as TreeComboBoxRenderer).treeSelectedItems.indexOf(data) != -1;
                        }
                        
                        label.x = startx;
                        label.setActualSize(unscaledWidth - startx, measuredHeight);
                        
                        var verticalAlign:String = getStyle("verticalAlign");
                        if (verticalAlign == "top")
                        {
                                _checkBox.y = 0;
                        }
                        else if (verticalAlign == "bottom")
                        {
                                _checkBox.y = unscaledHeight - _checkBox.height;
                        }
                        else
                        {
                                _checkBox.y = (unscaledHeight - _checkBox.height) / 2;
                        }
                }
                
                /**
                 * @private
                 */                
                protected function checkBoxClickHandler(event:MouseEvent):void
                {
                        event.stopPropagation();
                        
                        (owner as TreeComboBoxRenderer).updateSelectedItems(data, _checkBox.selected);
                }
                
                /**
                 * @private
                 */                
                protected function checkBoxMouseDownHandler(event:MouseEvent):void
                {
                        event.stopPropagation();        
                }
        }
}

抱歉!评论已关闭.