2009-03-04 16 views
4

Ich versuche, ein Datagrid zu erstellen, das die Größe vertikal ändert, um sicherzustellen, dass alle Renderer vollständig angezeigt werden. ZusätzlichFlex - Problem mit der automatischen Größenänderung von Datagrid

  • Renderers von variabler Höhe
  • Renderers sich
  • können die Größe

Im Allgemeinen ist der Fluss der Ereignisse wie folgt:

  • Einer der Renderer Artikel passt die Größe selbst (normalerweise als Reaktion auf einen Benutzerklick usw.)
  • Es löst ein Sprudlereignis aus, das vom übergeordneten Datagrid ausgelöst wird
  • Das DataGrid versucht, die Größe zu ändern, um sicherzustellen, dass alle Renderer vollständig sichtbar bleiben.

ich zur Zeit diesen Code innerhalb des Datagrid mit der Höhe zu berechnen:

height = measureHeightOfItems(0, dataProvider.length) + headerHeight; 

Dies scheint eine falsche Höhe zu erhalten. Ich habe eine Reihe von Varianten einschließlich callLater versucht (um sicherzustellen, dass die Größenänderung abgeschlossen wurde, so dass die Messung korrekt funktionieren kann), meausre() außer Kraft setzen und invalidateSize()/validateSize() aufrufen, aber keiner funktioniert.

Im Folgenden sind 3 Klassen, die das Problem veranschaulichen werden. Durch Klicken auf die Schaltfläche in den Elementrenderern wird die Größe des Renderers geändert. Das Raster sollte ebenfalls erweitert werden, sodass alle drei Renderer vollständig angezeigt werden.

Alle Vorschläge würden sehr geschätzt werden.

Grüße

Marty

DataGridProblem.mxml (Application-Datei)

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" 
    xmlns:view="view.*"> 
    <mx:ArrayCollection id="dataProvider"> 
     <mx:String>Item A</mx:String> 
     <mx:String>Item B</mx:String> 
     <mx:String>Item C</mx:String> 
    </mx:ArrayCollection> 
    <view:TestDataGrid 
     id="dg" 
     dataProvider="{ dataProvider }" 
     width="400"> 
     <view:columns> 
      <mx:DataGridColumn dataField="text" /> 
      <mx:DataGridColumn itemRenderer="view.RendererButton" /> 
     </view:columns> 
    </view:TestDataGrid> 
</mx:Application> 

view.TestDataGrid.as

package view 
{ 
    import flash.events.Event; 

    import mx.controls.DataGrid; 
    import mx.core.ScrollPolicy; 

    public class TestDataGrid extends DataGrid 
    { 
     public function TestDataGrid() 
     { 
      this.verticalScrollPolicy = ScrollPolicy.OFF; 
      this.variableRowHeight = true; 
      this.addEventListener(RendererButton.RENDERER_RESIZE , onRendererResize); 
     } 
     private function onRendererResize(event : Event) : void 
     { 
      resizeDatagrid(); 
     } 
     private function resizeDatagrid():void 
     { 
      height = measureHeightOfItems(0, dataProvider.length) + headerHeight; 
     } 
    } 
} 

view.RendererButton.mxml

<?xml version="1.0" encoding="utf-8"?> 
<mx:HBox xmlns:mx="http://www.adobe.com/2006/mxml"> 
    <mx:Button width="50" height="50" 
     click="onClick()" /> 

    <mx:Script> 
     <![CDATA[ 

      public static const RENDERER_RESIZE : String = "resizeRenderer"; 
      private function onClick() : void 
      { 
       this.height += 20; 
       dispatchEvent(new Event(RENDERER_RESIZE , true)); 
      } 
     ]]> 
    </mx:Script> 
</mx:HBox> 

Antwort

0

Für was es wert ist, habe ich es nie geschafft, dieses Problem zu lösen. Der Code wurde schnell besessen von Edge-Fällen.

Ich landete schließlich die DataGrid-Ansatz, und schrieb eine Lösung mit VBox & HBox, um die Größenänderung zu erleichtern.

+2

d'oh ... es muss einen Weg geben, damit das funktioniert. – DyreSchlock

0

Dinge wie variable Breite und Höhe Zellen/Zeilen/Spalten zu tun, wie auch andere „erweitern“ Funktionen - versuchen, die AdvancedDataGrid eher als die älteren erstreckt, langweiligen DataGrid

+0

Hi In diesem Fall ist die Verwendung von AdvancedDataGrid keine Option. Grüße Marty –

+0

Mit "langweilig" nehme ich an, du meinst "weniger buggy". – ggkmath

0

für was es wert ist; Sie sollten die VariableRowHeight = "True" -Eigenschaft des Datagrid/Advanced DataGrid verwenden.

Wenn es dich besser fühlen macht, habe ich die benutzerdefinierte VBox, HBox-Lösung dann nach dem entdeckt, dass es schon fertig ist !! (Snap !!)

viel Glück!

+0

Hallo Vusi Ich hatte bereits versucht, mit VariableRowWidth = True, aber es hat das Problem nicht gelöst (wie es scheint, du bist jetzt konfrontiert) –

0

Ihr Ansatz basiert auf einem zugrunde liegenden Problem. ItemRenderer sollen das Datenelement konsistent rendern. Wenn Sie den aktuellen Renderer auswerfen und einen neuen erstellen und die Dateneigenschaft des neuen Renderers festlegen, sollte er identisch mit dem vorherigen aussehen. Sie sollten keine transienten Änderungen an dem Renderer außerhalb des Datenelements vornehmen, und der Renderer wird sich auf merkwürdige Weise verhalten, wenn Sie dies tun.

Ich vermute, dass, wenn Sie Ihre Datenmodellobjekte so geändert haben, dass sie eine count-Eigenschaft und Daten enthalten, die Höhe des Renderers an den Ausdruck "{50 + data.count * 20}" gebunden und dann den Click-Handler der Schaltfläche inkrementiert. Zähle um 1, dass dies richtig funktionieren würde. (Meine Erfahrung ist, dass das DataGrid sich mit der richtigen Größe für jede Zeile neu zeichnet, solange die Änderungen als Ergebnis der Dateneigenschaft ausgeführt werden, bevor es makeRowsAndColumns() aufruft.) Ich habe diesen Ansatz für Ihr Beispiel nicht ausprobiert , also kann ich nicht mit Sicherheit sagen, dass es tatsächlich funktioniert, aber das ist sicherlich die richtige Einstellung für die Arbeit mit Elementrenderern.

2

Sie können dieses Ziel mit dem AdvancedDataGrid mithilfe des folgenden Codes erreichen. Wenn Sie this.headerHeight entfernen, funktioniert es auch für List, was mich glauben macht, dass es für das normale alte DataGrid funktionieren sollte.

override protected function measure():void 
    { 
    super.measure(); 

    if (this.dataProvider) 
    { 
    var newHeight : int = measureHeightOfItems(0, this.dataProvider.length) + this.headerHeight; 

    this.minHeight = newHeight; 
    this.height = newHeight; 
    } 
    } 
+0

Great stuff! Hier ist eine schönere Version: 'var newHeight: int = measureHeightOfItems (-1, dataProvider.length);' –

1

der Daten-Grid zur Laufzeit neu Größe .... verwenden rowcount Eigenschaft und binden Sie es mit der Dataprovider Länge. Wenn der Datenprovider aktualisiert wird, wird dies die Zeilenanzahl sein.
können Sie das Beispiel sehen, wie rowcount in Flex verwenden here

+0

funktioniert nicht, wenn variableRowHeight = "true" für Spark-Datagrids ist. – ggkmath

0

ich diese für ein solches Problem Versuchen Sie eine

private function ResizeGrid():void{ 
    if (this.dg.maxVerticalScrollPosition > 0){ 
     this.dg.height +=5; 
     setTimeout(this.ResizeGrid,100); 
    } 
} 

ein bisschen schmutzig Lösung haben und Ihre Funktion mit einer gewissen Verzögerung Rufen wie

folgt
setTimeout(this.ResizeGrid,100); 

Dies ist schmutzig Ansatz, aber es funktioniert für mich :)

0

Der folgende Code in gridItemRenderer mir geholfen:

protected function resize():void 
{ 
    column.grid.validateSize(); 
    column.grid.validateDisplayList(); 
} 
0

ich eine Lösung für dieses Problem haben, müssen Renderer Änderungen mit Ihrem Dataprovider synchronisieren. Dann gibt nur die Methode measureHeightOfItems genaue Ergebnisse.