代码之家  ›  专栏  ›  技术社区  ›  Jamie Love

带ComboBox项呈现器的灵活数据报

  •  9
  • Jamie Love  · 技术社区  · 15 年前

    我将尝试找出在flex(3.4)数据报中嵌入组合框的“正确”方法。根据权利(例如根据本页 http://blog.flexmonkeypatches.com/2008/02/18/simple-datagrid-combobox-as-item-editor-example/ )这应该很容易,但我这辈子做不到。

    与上面链接的示例不同的是,我的显示值(用户所看到的)与我要选择并存储在数据提供程序中的ID值不同。

    所以我有:

    <mx:DataGridColumn headerText="Type" width="200" dataField="TransactionTypeID" editorDataField="value" textAlign="center" editable="true" rendererIsEditor="true">
        <mx:itemRenderer>
            <mx:Component>
                <mx:ComboBox dataProvider="{parentDocument.transactionTypesData}"/>
            </mx:Component>
        </mx:itemRenderer>
    </mx:DataGridColumn>
    

    在哪里? transactionTypesData 同时具有“数据”和“标签”字段(根据 ComboBox -为什么它不能同时提供拉贝尔菲尔德和伊德菲尔德呢?我永远也不知道。

    无论如何,上面的MXML代码不能以两种方式工作:

    1. 组合框不与任何选定项一起显示。
    2. 选择项目后,它不会将所选项目存储回数据存储。

    那么,有没有人有类似的情况?

    3 回复  |  直到 11 年前
        1
  •  5
  •   Jamie Love    15 年前

    而Jeff的答案只是一种方法的部分答案(参见 http://flex.gunua.com/?p=119 作为一个完整的例子,它被用来取得良好的效果),它并不像我想要的那样一般。

    谢天谢地,我终于在 Experts Exchange (Hobbit72的答案)描述了如何创建一个在网格中作为项渲染器工作的自定义组件。 我已经扩展了代码以支持将组合框用作项编辑器。完整组件如下:

    <?xml version="1.0" encoding="utf-8"?>
    <mx:ComboBox
        xmlns:mx="http://www.adobe.com/2006/mxml" 
        dataChange="setSelected()" 
        change="onSelectionChange(event)"
        focusEnabled="true">
        <mx:Script>
            <![CDATA[
                import mx.events.DataGridEvent;
                import mx.events.ListEvent;
                import mx.controls.dataGridClasses.DataGridListData;
    
                private var _ownerData:Object;
                private var _lookupField:String = "value";
    
                // When using this component as an itemEditor rather than an itemRenderer
                // then set ' editorDataField="selectedItemKey"' on the column to 
                // ensure that changes to the ComboBox are propogated.
                [Bindable] public var selectedItemKey:Object;
    
                public function set lookupField (value:String) : void {
                    if(value) {
                        _lookupField = value;
                        setSelected();
                    }
                }           
                override public function set data (value:Object) : void {
                    if(value) {                    
                        _ownerData = value;
                        setSelected();
                    }
                }
                override public function get data() : Object {
                    return _ownerData;
                }            
                private function setSelected() : void {
                    if (dataProvider && _ownerData) {
                        var col:DataGridListData = DataGridListData(listData);
                        for each (var dp:Object in dataProvider) {
                            if (dp[_lookupField] == _ownerData[col.dataField]) {
                                selectedItem = dp;
                                selectedItemKey = _ownerData[col.dataField];
                                return;     
                            }
                        }                    
                    }
                    selectedItem = null;
                }
                private function onSelectionChange (e:ListEvent) : void {
                    if (selectedItem && _ownerData) {                    
                        var col:DataGridListData = DataGridListData(listData);
                        _ownerData[col.dataField] = selectedItem[_lookupField];
                        selectedItemKey = selectedItem[_lookupField];
                    }
                }                   
            ]]>
        </mx:Script>    
    </mx:ComboBox> 
    

    使用此组件是直接向前的。作为项呈现程序:

    <mx:DataGridColumn headerText="Child" dataField="PersonID" editable="false" textAlign="center">
      <mx:itemRenderer>
        <mx:Component>
          <fx:GridComboBox dataProvider="{parentDocument.childrenData}" labelField="Name" lookupField="PersonID" change="dispatchEvent(new mx.events.DataGridEvent(mx.events.DataGridEvent.ITEM_FOCUS_OUT, true, true))"/>
        </mx:Component>
      </mx:itemRenderer>                      
    </mx:DataGridColumn>
    

    使用此组件是直接向前的。作为项目编辑器:

    <mx:DataGridColumn labelFunction="lookupChildName" headerText="Child" dataField="PersonID" editable="true" editorDataField="selectedItemKey">
        <mx:itemEditor>
            <mx:Component>
                <fx:GridComboBox dataProvider="{parentDocument.childrenData}" labelField="Name" lookupField="PersonID" change="dispatchEvent(new mx.events.DataGridEvent(mx.events.DataGridEvent.ITEM_FOCUS_OUT, true, true))"/>
            </mx:Component>
         </mx:itemEditor>      
    </mx:DataGridColumn>
    

    请注意,当将其用作项编辑器时,必须使用自定义LabelFunction(在我的示例中从PersonID中查找名称),否则,您只能在未编辑字段时在网格中看到键(如果键/值相同,则不是问题)。

    注意,在我的例子中,我希望项目焦点输出事件能够向用户提供即时反馈(我的数据报 itemFocusOut="handleChange()" ) change 事件创建项目焦点事件。

    请注意,当您不介意组合框仅在用户单击要编辑的单元格时显示时,将组合框作为项编辑器可能有更简单的方法。我想要的方法是在数据报中为所有行显示一个组合框的通用方法,并且是可编辑的,并且具有适当的事件优先级。

        2
  •  2
  •   Jeff Pinkston    15 年前

    向数据报添加itemrenders的最简单方法是创建自定义MXML组件。在您的情况下,将画布、HBox或Vbox作为自定义组件,并将组合框作为子项添加。在DataGrid本身上设置DataProvider,并将itemRenderer分配给列,然后重写itemRenderer的set data函数以访问该实例的给定数据提供程序中的所有数据,如下所示:

    <mx:HBox xmlns:mx="http://www.adobe.com/2006/mxml">
    <mx:Script>
        <![CDATA[
    
            override public function set data(value:Object):void{
                        trace(value.data);
                        trace(value.name);
            }
        ]]>
       </mx:Script>
    
    <mx:ComboBox width="100%" height="100%" id="myComboBox"/>
     </mx:HBox>
    

    将为项呈现器的每个实例调用此方法

        3
  •  1
  •   Christo Smal    11 年前

    在我的例子中,我使用了Spark DataGrid,其中一列有一个使用DropDownListBox的项呈现器。我的问题是,当我的项目列表更改时,DropDownList不会用新的数据提供程序进行更新。为了解决这个问题,我必须将DropDownListBox的数据提供程序作为数据的一部分(项渲染器)传递,然后通过重写数据的设置器来分配DropDownListBox的数据提供程序。可能有点开销,但是如果有人有更好的解决方案,请告诉我:

    <s:GridItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009" 
                    xmlns:s="library://ns.adobe.com/flex/spark" 
                    xmlns:mx="library://ns.adobe.com/flex/mx">
    <fx:Script>
        <![CDATA[
            override public function set data(v : Object) : void {
                super.data = v;
                if (v == null)
                    return;
                dropDown.dataProvider = data.dataProvider;
            }
        ]]>
    </fx:Script>
    <s:DropDownList id="dropDown" width="100%" height="100%" dataProvider="{data.dataProvider}" labelField="name"/>
    

    推荐文章