【问题标题】:Flex Spark ComboBox in an MX AdvancedDataGridMX AdvancedDataGrid 中的 Flex Spark ComboBox
【发布时间】:2011-04-13 13:24:31
【问题描述】:

我想将组合框用作 AdvancedDataGrid 的其中一列的 itemEditor。我环顾四周,决定使用 Spark ComboBox 组件——它们很漂亮,而且似乎原生支持很多简洁的东西,包括在 textInput 中键入时自动完成字符串。经过一番修补后,我设法在我的 ADG 中添加了一个 spark ComboBox,设置了它的数据提供程序,以便在用户添加新项目时扩展它,并将其全部连接起来。结果似乎很有希望,但与往常一样,一些细节对我来说是无法克服的(实际上我还不是一个 flex 专业人士),并希望有人能指出我正确的方向。代码粘贴在下面,并使用此处描述的技巧将 spark 组件用作 mx 网格的 itemEditor。

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

  1. 如果您开始在 ComboBox 中输入内容并在所需项目出现时按 Enter,则 ComboBox 将保持为空
  2. 如果您在 ComboBox 中键入新项目并按 Enter,则该项目将添加到数据提供程序(正确的行为)但 ComboBox 仍然为空
  3. 当您第一次单击单元格时,其当前值也会消失

我调试了前两个烦人的场景,似乎按下 Enter 会导致在 myCB_changeHandler 之前调用 advanceddatagrid1_itemEditEndHandler,这意味着当 dataGrid 在其单元格上进行更新时永远不会设置 myRetVal。如果从列表中进行选择,则会发生相反的情况,即有效的情况。不过不知道该怎么办:-(

还想就第三个恼人的症状提出建议。

谢谢!

f


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>        

和组件

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

【问题讨论】:

    标签: apache-flex actionscript-3 combobox flex4 advanceddatagrid


    【解决方案1】:

    所以,亲爱的 Fred,我阅读了您的帖子,并获得了一些关于绑定的想法,如下所示:

    &lt;mx:Binding destination="value" source="cbo.value"/&gt;

    在您的组件内部。

    另外我hereKyle 解释了他的愿景。有了这个想法,我认为将其切换为 spark 组件没有问题。

    如果有帮助,请告诉我。

    谢谢。

    【讨论】:

    • 尤金感谢您的建议。我假设你的意思是做这样的事情 ?不幸的是,这似乎不起作用......不过我会查看链接。
    • 好的,查看帖子 - 不幸的是,我不认为这也能解决问题......不知何故,上面的代码缺少它的标题,即 。原来 s:MXAdvancedDataGridItemRenderer 实现了 IDropInListItemRenderer 和 IFocusManagerComponent 所以我不认为这是问题所在。不过还是谢谢...
    • 我将尝试为 ADG 再次确认此问题,因为它适用于 DataGrid。
    【解决方案2】:

    好吧,历经千辛万苦,我发现:

    • 覆盖方法集数据似乎可以解决问题 3 - 在阅读了更多标准 adobe flex 文献(顺便说一句很棒)之后,这很有意义。像这样的东西应该可以解决问题

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-07-08
      • 2010-12-15
      • 2011-12-25
      • 2011-08-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多