Frage

Ich werde Ersatz versuchen, die „richtigen“ Weg, um herauszufinden, eine ComboBox in einem Flex (3.4) Datagrid einzubetten. Durch Rechte (zB nach dieser Seite http://blog.flexmonkeypatches.com/2008/02/18/simple-datagrid-combobox-as-item-editor-example/ ) sollte es einfach sein, aber ich kann mich nicht für das Leben machen diese Arbeit.

Der Unterschied, den ich auf das Beispiel oben verbunden ist, dass mein Anzeigewert (was der Benutzer sieht) mit dem id-Wert unterscheidet ich in meinem Datenanbieter auszuwählen, auf und speichern möchten.

Also, was ich habe, ist:

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

Wo transactionTypesData sowohl ‚Daten‘ und ‚Label‘ Felder (laut, was die ComboBox - warum auf der Erde ist es nicht schaffen, sowohl ein labelField- und idField Ich werde nie wissen).

Wie auch immer, die oben MXML-Code nicht funktioniert auf zwei Arten:

  1. Das Kombinationsfeld zeigt nicht mit jedem ausgewählten Artikel auf.
  2. Nach der Auswahl eines Elements, speichert es nicht, dass die ausgewählten Artikel auf den Datenspeicher zurück.

Also, hat jemand bekam eine ähnliche Situation zu arbeiten?

War es hilfreich?

Lösung

Während Jeffs Antwort eine Teilantwort für einen Ansatz hierfür ist (siehe http: // flex. gunua.com/?p=119 für ein komplettes Beispiel für dieses Wesen mit guter Wirkung verwendet), es ist nicht so allgemein wie ich wollte.

Zum Glück fand ich endlich eine große Hilfe auf Experten-Austausch (die Antworten von hobbit72) beschreibt, wie eine benutzerdefinierte Komponente erstellen, die als ItemRenderer in einem Raster arbeitet. Ich habe diesen Code erweitert auch unterstützen als auch das Kombinationsfeld als ItemEditor verwenden. Die vollständige Komponente ist wie folgt:

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

Mit dieser Komponente ist geradlinig. Als 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>

Mit dieser Komponente ist geradlinig. Und als 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>

Beachten Sie, dass, wenn es als ItemEditor, ein Brauch mit labelfunction (dass der Namen aus dem PersonID in meinem Fall schaut nach oben) verwendet werden muss, sonst nur Sie den Schlüssel in dem Netz sehen, wenn das Feld nicht bearbeitet wird ( kein Problem, wenn Ihre Schlüssel / Werte sind gleich).

Beachten Sie, dass in meinem Fall, ich das Element wollte Ereignis konzentrieren, um ein unmittelbares Feedback zu propagieren bis zu liefern dem Benutzer (mein Datagrid hat itemFocusOut="handleChange()"), daher der change Ereignis eine ITEM_FOCUS_OUT Veranstaltung.

Beachten Sie, dass es wahrscheinlich einfache Weise ist eine ComboBox als ItemEditor zu haben, wenn Sie nur dann angezeigt, nicht die ComboBox Sinn, wenn der Benutzer klickt auf der Zelle zu bearbeiten. Der Ansatz, den ich wollte, war eine generische Art und Weise ein Kombinationsfeld in einem Datagrid für alle Zeilen zu zeigen, und ist editierbar und mit anständigem Ereignisse propogation.

Andere Tipps

Der einfachste Weg itemRenderers zu Datagrids hinzuzufügen ist, um eine benutzerdefinierte MXML-Komponente zu machen. In Ihrem Fall macht eine Leinwand, HBox oder VBox als benutzerdefinierte Komponente und fügen Sie die Combobox als child.Set die Datenprovider auf dem Datagrid selbst und die itemRenderer auf die Spalte zuweisen, und dann überschreiben die eingestellten Daten in Abhängigkeit von den itemRenderer zugreifen Alle Daten aus dem gegebenen Datenprovider für diese Instanz wie unten zu sehen:

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

Dieses Verfahren wird für jede Instanz des itemRenderer aufgerufen werden

In meinem Fall habe ich einen Funken Datagrid verwendet, in denen eine der Spalten einen ItemRenderer hat, die eine DropDownListBox nutzt. Mein Problem war, dass, wenn meine Artikelliste ändern, wird die Dropdownlists nicht mit dem neuen Datenprovider aktualisiert. Um dies zu lösen, hatte ich die Datenprovider für die DropDownListBox als Teil der Daten (des ItemRenderer) passieren, und dann durch den Einrichter der Daten überschreiben, um nur die Datenprovider des DropDownlListBox zuweisen. Wahrscheinlich ein wenig von Overhead, aber wenn jemand eine bessere Lösung haben, informieren Sie mich bitte:

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

    

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top