• Flex 扩展combobox 实现复选功能


         前段时间,老大召唤,给个任务,研究一下flex的combobox控件 实现复选功能(flex自带的combobox控件不可以复选),小兵能力有限,哪里可以扩展呀,网上看了别人写的,发现总是有点瑕疵(关键是还没有注释这个是最蛋疼的):

         1.静态数据源正常,动态数据源 第一次点击时 没有取到数据,下拉列表为空。

         2. ROLL_OVER  ROLL_OUT 监听混乱,选择一项后下拉框突然收缩了,或者选择几项下拉框突然收缩了。

         3.返回值有误,显示选中的项 与 实际返回选中的项不符

    分析:

      ROLL_OVER 与 ROLL_OUT 区别:

      ROLL_OVER:就是鼠标从外部移入该组件才调用, ROLL_OUT 就是鼠标移到该组件外部才调用

    另外 其他两个:MOUSE_OVER 与MOUSE_OUT 区别类似

      ROLL_* 与MOUSE_* 的区别是:

        MOUSE_*:鼠标 进入/移 出该组件时会调度MOUSE_*事件,即使是从其子组件移到该组件依然会触发该事件

        ROLL_* :鼠标从不是其子组件的其余组件中进入该组件时会调度ROLL_*事件

    下面是扩展后的代码,修复了上面提到的瑕疵:

    必要部分已经加上了注释

    MultipleComboBox.cs

    package common
    {
        import flash.events.Event;
        import flash.events.MouseEvent;
        
        import mx.collections.ArrayCollection;
        import mx.controls.ComboBox;
        import mx.core.ClassFactory;
        import mx.events.FlexEvent;
        import mx.events.ListEvent;  
      
        public class MultipleComboBox extends ComboBox{  
            private var mouseOut:Boolean=false;
           [Bindable]  
            private var promptText:String="";   //复选框收缩后显示label的值
            private var selArr:Array=[];         //复选框选中值集合
            private var splitStr:String="/";    //选中多个值 以此分割
           public function MultipleComboBox(){  
                super();  
                this.addEventListener(FlexEvent.CREATION_COMPLETE,onCreateCompleteHandle);
                //多选ComboBox 内嵌CheckBox实现
                this.itemRenderer=new ClassFactory(CheckBoxItemRenderer);             
            }  
            private function onCreateCompleteHandle(event:FlexEvent):void{
                dropdown.allowMultipleSelection=true; 
                close(); 
                //
                mouseOut=false; //置为false
            }  
            //监听鼠标一入一出
            private function initListener():void{  
                if(!dropdown.hasEventListener(MouseEvent.ROLL_OVER))  
                    dropdown.addEventListener(MouseEvent.ROLL_OVER,onRollOverHandle);  
                if(!dropdown.hasEventListener(MouseEvent.ROLL_OUT))  
                    dropdown.addEventListener(MouseEvent.ROLL_OUT,onRollOutHandle);  
            }
            private function onRollOverHandle(event:MouseEvent):void{  
                mouseOut=false;  
            }  
            private var changeEvent:ListEvent;  
            //ROLL_OUT 更改选中值集合
            private function onRollOutHandle(event:MouseEvent):void{ 
                var list:ArrayCollection=ArrayCollection(this.dataProvider);
                mouseOut=true;  
                var selectedStr:String = "";  //复选框收缩后的label,此处以"/"分割显示选中的值
                selArr=[];//每次清空selArr保存的值
                for each(var obj:Object in list)  //遍历数据源,向selArr数组添加状态selected=true(选中)的值
                {    
                    if(obj.selected){
                        selectedStr += obj.Code+this.splitStr;
                        selArr.push(obj);
                    }        
                }
                this.selectedItems=selArr;
                this.promptText = selectedStr.substring(0,selectedStr.length -1) ;  
                
                close(); //鼠标移出 收缩 
                //
                mouseOut=false; //置为false
                
                changeEvent= new ListEvent( ListEvent.CHANGE )  
                dispatchEvent( changeEvent);
                trace(this.text);
            }  
            //ComboBox 带有selectedItems属性 但只实现selectedItem,此处实现selectedItems
            public function set selectedItems(value:Array):void{  
                if (dropdown){  
                    dropdown.selectedItems=value;
                }
                this.selArr=value;
            }  
      
            [Bindable("change")]  
            public function get selectedItems():Array{ 
                return selArr; 
           } 
            override public function close(trigger:Event=null):void{  
                //initListener();  
                if (mouseOut){  
                    super.close(trigger);  
                }  
                this.textInput.text=promptText; 
                this.toolTip = promptText;
                initListener();//此处需要从上面注释处调整到这里,
                //因为 CheckBoxItemRender中的 this.addEventListener(Event.CHANGE,onClickCheckBox)监听导致
                //基数次单击时mouseOut=true; 直接下拉框收缩
            }  
            override public function set prompt(value:String):void{  
                promptText=value;  
            }  
            public function set split(value:String):void
            {
                this.splitStr=value;
            }
            public function get split():String
            {            
                return splitStr;
            }
        }  
    }

    CheckBoxItemRenderer.cs:

    package common
    {
        import flash.events.Event;
        
        import mx.collections.ArrayCollection;
        import mx.controls.CheckBox;
        import mx.controls.List;
        import mx.utils.ArrayUtil;
        
        import configuration.FormatConfig;
        
        public class CheckBoxItemRenderer extends CheckBox{
            
            /**存储当前列数据对象**/
            private var currData:Object; 
            
            public function CheckBoxItemRenderer(){
                super();
                this.addEventListener(Event.CHANGE,onClickCheckBox);
            }
            
            override public function set data(value:Object):void{
                if(value !=null)
                {
                    this.selected = value.selected;
                    this.currData = value; 
                    //此处CheckBox label显示code+name 可根据需要置
                    this.label=value.Code+"  "+value.Name;   
                }
                else
                {
                    this.label=null;
                }
            }
            //此属性可设置 数据源任意一项不可选 (enabled)
            override public function set enabled(value:Boolean):void{  //
                if(currData){
                    value=currData.enabled==false?false:true;
                }
                super.enabled=value;
            }
            /*更改被选中项的状态selected=true*/
            private function onClickCheckBox(e:Event):void{    
                var list:ArrayCollection=ArrayCollection(List(this.parent.parent).dataProvider);//获取数据源
                for each(var obj:Object in list)
                {
                    //label的值为数据源中code + name 拼接的 所以此处判断某一项是否被选中的条件看上去有点怪
                    if((obj.Code+"  "+obj.Name)==this.label){ 
                        if(this.selected){
                            obj.selected=true;   //选中状态selected=true
                        }else{
                            obj.selected=false;  //为选好
                        }
                        //break;
                    }
                }
            }
        }
    }

    由于扩展的不够通用,所以使用的时候稍微做点处理

    应用 Temp.mxml文件

    <?xml version="1.0" encoding="utf-8"?>
    <mx:Module  xmlns:fx="http://ns.adobe.com/mxml/2009" 
                xmlns:s="library://ns.adobe.com/flex/spark" 
                xmlns:mx="library://ns.adobe.com/flex/mx"
                xmlns:common="common.*"
                creationComplete="module_creationCompleteHandler(event)"
                xmlns:mywebservice="services.mywebservice.*">
        <fx:Script>
            <![CDATA[
                import mx.rpc.soap.WebService;
                import spark.components.Scroller;
                import spark.components.VScrollBar;
                import spark.events.IndexChangeEvent;
                
                [Bindable]
                private var datacbbSource:ArrayCollection;
                
                private function ShowSelectItems2():void{
                    info2.text="";
                    info2.text+="选中了 "+myCombox2.selectedItems.length+" 个选项!
    ";
                    for each(var item:Object in myCombox2.selectedItems){
                        info2.text+=ObjectUtil.toString(item)+"
    ";
                    }
                }
                
                var num=0;
                private function module_creationCompleteHandler(event:FlexEvent):void 
                {
                    GetDataResult.token = mywebservice.GetData(); //获取数据源
                }
                
                [Bindable]
                private var dataGrideSource:ArrayCollection;
                
                protected function GetAllShopsResult_resultHandler(event:ResultEvent):void
                {
                    // TODO Auto-generated method stub
                    var result:ArrayCollection=event.result as ArrayCollection;
                    if (result == null || result.length == 0)
                    {                
                        return;
                    }
                    this.datacbbSource=new ArrayCollection();
    for each(var item in result) { datacbbSource.addItem({Code:item.Code,Name:item.Name,selected:false}); } } ]]> </fx:Script> <fx:Declarations> <s:CallResponder id="GetDataResult" result="GetDataResult_resultHandler(event)" /> <shopservice:MyWebService id="mywebService" /> </fx:Declarations> <s:VGroup width="100%" height="100%" paddingLeft="10" paddingRight="10" paddingBottom="10" paddingTop="3"> <s:HGroup width="100%" color="black" verticalAlign="middle" height="296"> <common:MultipleComboBox width="200" id="myCombox2" split=";" prompt="请选择" > <s:ArrayCollection list="{datacbbSource}"/> </common:MultipleComboBox> <mx:Text id="info2"/> <s:Button label="点击查看选择数据" click="ShowSelectItems2()"/> </s:HGroup> </s:VGroup> </mx:Module >

    运行结果就不上图了,下面这段

    for each(var item in  result)
    {
         datacbbSource.addItem({Code:item.Code,Name:item.Name,selected:false});
    }

         对数据源做了处理,强制转换成含有Code,Name,selected(默认值false)三个属性的对象,因为在CheckBoxItemRenderer.cs 和MultipleComboBox.cs文件中使用到的参数直接使用到了Code,Name,selected属性。

        最后虽然最终这个没有应用到项目中,为了以后用到时方便,记录一下。

    继续充电中。。。。

    扩展代码参考:http://liu-yi126.iteye.com/blog/1305494

     
  • 相关阅读:
    JAVA 单例模式
    CodeForces Round #563 Div.2
    拓扑排序 JAVA
    初识 Dubbo
    CodeForces Round #567 Div.2
    Educational Codeforces Round 65 (Rated for Div. 2)
    最短路径问题
    C++使用fixed和precision控制小数和有效位数的输出以及setw()设置输出宽度
    poj3684(弹性碰撞模型)
    集合的整数表示
  • 原文地址:https://www.cnblogs.com/ashleyboy/p/3669269.html
Copyright © 2020-2023  润新知