9

Flex(3.4)DataGrid内にComboBoxを埋め込むための「正しい」方法を理解しようとはしません。権利によって(例えば、このページ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'data'フィールドと'label'フィールドの両方がある場所(何が原因でComboBox-なぜ地球上でlabelFieldとidFieldの両方が提供されないのか私にはわかりません)。

とにかく、上記のMXMLコードは2つの方法で機能しません。

  1. コンボボックスは、選択したアイテムとともに表示されません。
  2. アイテムを選択した後、その選択したアイテムをデータストアに保存しません。

それで、誰かが同じような状況で働いていますか?

4

3 に答える 3

5

ジェフの答えは、このための1つのアプローチに対する部分的な答えですが(これが効果的に使用されている完全な例については、http://flex.gunua.com/ ?p = 119を参照してください)、私が望んでいたほど一般的ではありません。 。

ありがたいことに、私はついにExperts Exchange(hobbit72による回答)でItemRendererとしてグリッドで機能するカスタムコンポーネントを作成する方法を説明しているいくつかの素晴らしいヘルプを見つけました。そのコードを拡張して、コンボボックスをItemEditorとしても使用できるようにしました。完全なコンポーネントは次のとおりです。

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

このコンポーネントの使用は簡単です。ItemRendererとして:

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

このコンポーネントの使用は簡単です。そしてItemEditorとして:

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

ItemEditorとして使用する場合は、カスタムlabelFunction(私の場合はPersonIDから名前を検索する)を使用する必要があることに注意してください。そうしないと、フィールドが編集されていないときにのみグリッドにキーが表示されます(問題ありません)。キー/値が同じ場合)。

私の場合、アイテムフォーカスアウトイベントを伝播して、ユーザーに即座にフィードバックを提供する必要があることに注意してください(私のDataGridにはitemFocusOut="handleChange()")。したがって、changeイベントはITEM_FOCUS_OUTイベントを作成します。

ユーザーが編集するセルをクリックしたときにのみ表示されるComboBoxを気にしない場合は、ComboBoxをItemEditorとして使用するより簡単な方法があることに注意してください。私が望んでいたアプローチは、すべての行のDataGridにコンボボックスを表示し、編集可能で、適切なイベント伝播を使用する一般的な方法でした。

于 2009-09-17T01:14:22.543 に答える
2

itemRenderersをDataGridsに追加する最も簡単な方法は、カスタムMXMLコンポーネントを作成することです。この場合、カスタムコンポーネントとしてキャンバス、HBox、またはVBoxを作成し、コンボボックスを子として追加します.dataGrid自体にdataProviderを設定し、itemRendererを列に割り当ててから、itemRendererのsetdata関数をオーバーライドしてアクセスします以下に示すように、そのインスタンスの特定のデータプロバイダーからのすべてのデータ:

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

このメソッドは、itemRendererのインスタンスごとに呼び出されます

于 2009-09-14T18:30:14.633 に答える
1

私の場合、列の1つにDropDownListBoxを利用するItemRendererがあるsparkデータグリッドを使用しました。私の問題は、アイテムリストが変更されたときに、DropDownListsが新しいdataProviderで更新されないことでした。これを解決するには、DropDownListBoxのdataProviderを(ItemRendererの)データの一部として渡し、データのセッターをオーバーライドして、DropDownlListBoxのdataProviderを割り当てる必要がありました。おそらく少しオーバーヘッドがありますが、誰かがより良い解決策を持っている場合は、私に知らせてください:

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

于 2014-02-02T13:16:22.763 に答える