MX AdvancedDataGrid中的Flex Spark ComboBox

时间:2010-09-17 04:34:04

标签: flex actionscript-3 combobox flex4 advanceddatagrid

我想使用组合框作为AdvancedDataGrid的其中一列的itemEditor。我环顾四周,决定使用Spark ComboBox组件 - 它们很光滑,似乎本身支持很多简洁的东西,包括在textInput中的类型时自动完成字符串。经过一些修修补补后,我设法为我的ADG添加一个Spark ComboBox,设置其数据提供程序,以便在用户添加新项目时进行扩展,并将其全部挂起。结果似乎很有希望,但一如既往,我无法克服一些细节(事实上我还不是一个灵活的专业人士),并希望有人能指出我正确的方向。代码粘贴在下面,并使用此处描述的技巧将spark组件用作mx网格的itemEditor。

如果您使用(超级简单)应用程序,您会注意到如果您在右侧最后一列上单击(几次)并打开ComboBox,您可以从列表中选择一个值,单击另一个单元格,所选值将显示在刚刚离开的单元格中。然而,这里开始讨厌的事情列表:

  1. 如果您开始在ComboBox中输入并在所需项目出现时按Enter键,则ComboBox将保持为空
  2. 如果您在ComboBox中键入新项目并按Enter键,该项目将添加到数据提供者(正确行为),但ComboBox仍然为空
  3. 当您第一次点击某个单元格时,其当前值也会消失
  4. 我调试了前两个恼人的场景,似乎按Enter导致在myCB_changeHandler之前调用advanceddatagrid1_itemEditEndHandler,这意味着当dataGrid对其单元格进行更新时,myRetVal永远不会被设置。如果从列表中选择,即有效的情况,则会发生相反的情况。不知道该怎么办呢: - (

    也会喜欢有关第三种烦人症状的建议。

    谢谢你!

    ˚F


    MXML App

    <fx:Declarations>
        <s:ArrayCollection id="myCbDb"/>
    
    </fx:Declarations>
    
    <fx:Script>
        <![CDATA[
            import mx.collections.ArrayCollection;
            import mx.events.AdvancedDataGridEvent;
            import mx.events.DataGridEventReason;
            import mx.events.FlexEvent;
    
            [Bindable]
            public var dataProv:ArrayCollection = new ArrayCollection();
    
    
            [Bindable]
            private var dpADG:ArrayCollection = new ArrayCollection([
                {Name:'Pavement', duration:10, complete:0.1, ownerResource:'jon'},
                {Name:'Pavement', duration:20, complete:.2, ownerResource:'randy'},
                {Name:'Saner', duration:30, complete:.30, ownerResource:'joe'},
                {Name:'Saner', duration:10, complete:.40, ownerResource:'mia'},
                {Name:'The Doors', duration:5, complete:.50, ownerResource:'mia'},
                {Name:'The Doors', duration:0, complete:.60, ownerResource:'jill'},
                {Name:'Grateful Dead', duration:20, complete:.70, ownerResource:'jill'},
                {Name:'Grateful Dead', duration:10, complete:.80, ownerResource:'joe'},
                {Name:'Grateful Dead', duration:10, complete:.90, ownerResource:'jon'},
                {Name:'The Doors', duration:5, complete:1, ownerResource:'jon'},
                {Name:'The Doors', duration:10, complete:0, ownerResource:'jon'}
            ]);                   
    
            private function formatDuration(data:Object, column:AdvancedDataGridColumn):String
            {
                var retVal:String = "";
                var duration:Number = data[column.dataField] as Number;
                retVal = duration.toString() + " days";
                return retVal;
            }
    
            private function formatComplete(data:Object, column:AdvancedDataGridColumn):String
            {
                var retVal:String = "";
                var duration:Number = data[column.dataField] as Number;
                duration *= 100;
                retVal = duration.toString() + " %";
                return retVal;
            }
    
            private function formatResources(data:Object, column:AdvancedDataGridColumn):String
            {
                var retVal:String = data[column.dataField] as String;
                return retVal;
            }
    
    
    
            protected function advanceddatagrid1_creationCompleteHandler(event:FlexEvent):void
            {
                for each (var a:Object in dpADG.source)
                {
                    var s:String = a["ownerResource"];
                    if (!dataProv.contains(s))
                    {
                        dataProv.addItem(s);
                        trace("adding element ", s);
                    }
                }
            }
    
    
            protected function advanceddatagrid1_itemEditEndHandler(event:AdvancedDataGridEvent):void
            {
                if (event.dataField == "ownerResource")
                {
                    var editor:ResourceComboBoxField = ADG.itemEditorInstance as ResourceComboBoxField;
                    var name:String = editor.myRetVal; 
                    // handle the ESC case first off
                    if (event.reason == DataGridEventReason.CANCELLED)
                    {
                        // Do not update cell.
                        return;
                    }
    
                    // do something with myRetVal if needed be          
                }
            }
    
        ]]>
    </fx:Script>
    
    <mx:AdvancedDataGrid 
        width="100%" height="100%"
        id="ADG"
        sortExpertMode="true"
        editable="true"
        creationComplete="advanceddatagrid1_creationCompleteHandler(event)"
        dataProvider="{dpADG}"
        itemEditEnd="advanceddatagrid1_itemEditEndHandler(event)">
        <mx:columns>
            <mx:AdvancedDataGridColumn dataField="Name" />
            <mx:AdvancedDataGridColumn dataField="duration" labelFunction="formatDuration" itemEditor="DurationField" editorDataField="value"/>
            <mx:AdvancedDataGridColumn dataField="complete" labelFunction="formatComplete" itemEditor="CompleteField" editorDataField="value"/>
            <mx:AdvancedDataGridColumn dataField="ownerResource" labelFunction="formatResources" editorDataField="myRetVal">
                <mx:itemEditor>
                    <fx:Component>
                        <local:ResourceComboBoxField myDP="{outerDocument.dataProv}">
    
                        </local:ResourceComboBoxField>
                    </fx:Component>
                </mx:itemEditor>
            </mx:AdvancedDataGridColumn>
    
        </mx:columns>
    </mx:AdvancedDataGrid>        
    

    和组件

    <fx:Script>
        <![CDATA[
            import mx.collections.ArrayCollection;
            import mx.collections.IList;
    
            import spark.events.IndexChangeEvent;
    
            public var myRetVal:String = new String();
    
            [Bindable]
            public var myDP:ArrayCollection;
    
            // Event handler to determine if the selected item is new.
            protected function myCB_changeHandler(event:IndexChangeEvent):void
            {
                // Determine if the index specifies a new data item.
                if(myCB.selectedIndex == spark.components.ComboBox.CUSTOM_SELECTED_ITEM)
                    // Add the new item to the data provider.
                    myDP.addItem(myCB.selectedItem);
    
                myRetVal = myCB.selectedItem;
            }
    
        ]]>
    </fx:Script>
    
    <s:ComboBox id="myCB" width="140" change="myCB_changeHandler(event);" dataProvider="{myDP}"/>
    

2 个答案:

答案 0 :(得分:0)

所以,我读了你的帖子,亲爱的弗雷德,并得到一些关于绑定的想法,如下:

<mx:Binding destination="value" source="cbo.value"/>

您的组件内部。

我也是here凯尔解释他的愿景。我认为用这个想法将它切换到spark组件没有问题。

如果有帮助,请告诉我。

谢谢。

答案 1 :(得分:0)

好的,经过多次苦难,我发现:

  • 覆盖方法集数据似乎解决了问题3 - 在阅读了更多标准的adobe flex文献(BTW非常棒)之后,这很有意义。像这样的东西应该做的伎俩

        override public function set data(value:Object):void 
        {
            myCB.selectedItem = value.ownerResource;
            myCB.validateNow();
        }
    
  • CB的标准行为似乎是回到旧值(即,如果按ESC键,通常会发生什么),如果您输入了一个名称,然后按回车键。不知道如何改变这种行为,但

  • 问题1和2是由于原始值未设置,因此默认为填充空值的预览值。