简体   繁体   English

MX AdvancedDataGrid中的Flex Spark ComboBox

[英]Flex Spark ComboBox in an MX AdvancedDataGrid

I would like to use a combobox as the itemEditor for one of the columns of an AdvancedDataGrid. 我想使用组合框作为AdvancedDataGrid列之一的itemEditor。 I looked around and decided to use Spark ComboBox components - they're slick and seem to natively support a lot of neat stuff including auto-completing strings when types in the textInput. 我环顾四周,决定使用Spark ComboBox组件-它们很光滑,并且似乎本机支持许多简洁的东西,包括在textInput中键入时自动完成字符串。 After some tinkering I managed to add a spark ComboBox to my ADG, setup its data provider in order for it to expand as the user adds new items, and hook it all up. 经过一番修补后,我设法在我的ADG中添加了一个火花ComboBox,设置了它的数据提供程序,以便在用户添加新项目时扩展它,并将其连接起来。 The result seems promising, but as always, a few details have been impossible to overcome for me (indeed I'm not a flex pro quite yet) and was hoping that someone could point me in the right direction. 结果似乎很有希望,但与往常一样,我无法克服一些细节(实际上我还不是Flex Pro),并希望有人可以指出正确的方向。 The code is pasted below and uses the tricks described here to use a spark component as an itemEditor for an mx grid. 该代码粘贴在下面,并使用此处介绍的技巧将spark组件用作mx网格的itemEditor。

If you play with the (super simple) app you will notice that if you click (a couple of times) on the last column to the right and open the ComboBox you can pick a value from the list, click on a different cell, and the selected value will appear in the cell you just left. 如果您使用(超级简单)应用程序,您会注意到,如果您单击(几次)右侧最后一列并打开ComboBox,则可以从列表中选择一个值,单击另一个单元格,然后所选值将出现在您刚离开的单元格中。 However, and here starts the list of annoying things: 但是,这里开始列出烦人的事情:

  1. if you start typing in the ComboBox and press enter when the desired item comes up the ComboBox will remain empty 如果您开始在ComboBox中输入内容,并在出现所需项目时按Enter键,则ComboBox将保持空白
  2. if you type a new item in the ComboBox and press enter the item gets added to the data provider (correct behavior) but the ComboBox still remains empty 如果您在ComboBox中键入新项目并按Enter,则该项目将被添加到数据提供程序中(正确的行为),但ComboBox仍然为空
  3. when you first click on a cell its current value also disappears 当您第一次单击一个单元格时,其当前值也会消失

I debugged the first two annoying scenarios and it seems that pressing Enter leads to advanceddatagrid1_itemEditEndHandler being called before myCB_changeHandler, which means that myRetVal is never set when the dataGrid does its update on its cells. 我调试了前两个烦人的场景,似乎按Enter导致在myCB_changeHandler之前调用advanceddatagrid1_itemEditEndHandler,这意味着当dataGrid在其单元格上进行更新时,永远不会设置myRetVal。 The opposite happens if one selects from the list, ie the case that works. 如果从列表中进行选择,则会发生相反的情况,即可行的情况。 Not sure what to do about it though :-( 虽然不知道该怎么办:-(

Would also love advice on the third annoying symptom. 也会喜欢第三种烦人症状的建议。

thank you! 谢谢!

f F


The MXML App MXML应用

<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>        

and the component 和组件

<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}"/>

So, I read your post, dear Fred, and get some ideas about binding, like this: 因此,亲爱的Fred,我读了您的文章,并获得了一些有关绑定的想法,例如:

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

Inside of your component. 在组件内部。

Also I here Kyle explain his vision. 在这里也向凯尔解释他的愿景。 And I see no problem to switch it to spark component, with that idea. 而且我认为,将其转换为Spark组件没有问题。

Let me know please, if it helps. 如果有帮助,请告诉我。

Thank you. 谢谢。

Ok, after much tribulation, I found that: 好了,经过很多苦难,我发现:

  • overriding the method set data seems to fix issue 3 - it makes a lot of sense after reading a lot more of the standard adobe flex literature (which BTW is awesome). 覆盖方法集数据似乎可以解决问题3-在阅读了更多的标准Adobe Flex文献(BTW很棒)之后,这很有道理。 Something like this should do the trick 这样的事情应该可以解决问题

      override public function set data(value:Object):void { myCB.selectedItem = value.ownerResource; myCB.validateNow(); } 
  • the standard behavior of a CB seems to be to go back to an old value (ie what normally happens if pressing ESC) if you're typing a name and then press enter. 如果您输入名称然后按Enter,则CB的标准行为似乎是返回到旧值(即,按ESC通常会发生的情况)。 Not sure how to change that behavior, but 不确定如何更改该行为,但是

  • issues 1 and 2 were due to the fact that the original value had not been set, and thus defaulting to the previews value filled with an empty value. 问题1和2是由于未设置原始值,因此默认为填充有空值的预览值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM