2011-09-14 58 views
1

我有一個AdvancedDataGrid變量行高設置爲true。 我已經寫了一個基於DataGroup spark組件的cutsom項目渲染器。網格中的每一行都有多個要顯示的實體,實體的x位置和寬度基於實體本身的數據。ItemRenderer高度(和高度變化)沒有反映在AdvancedDataGrid行

我有一個爲DataGroup編寫的自定義佈局,它根據其數據度量和定位每個實體。每行中的每個實體可以截斷或不截斷其標籤。當標籤未被截斷時,我計算對象的實際寬度並在DataGroup的佈局的度量方法中手動驗證其大小(強制標籤具有正確的寬度和佈局所有文本行並重新測量自身)以精確測量數據組本身。

佈局,測量,大小,顯示等都正常工作。實體在不截斷標籤時報告它們所需的正確高度,數據組報告繪製其所有行的實體所需的正確大小(全部來自測量方法,例如它們需要在UIComponent生命週期下)。

當在AdvancedDataGrid本身內部時,行的大小不正確。大多數行不需要多行並顯示得很好。那些需要多行的行具有較大的行高,但在大多數情況下不足以容納整個文本。該行的DataGroup(及其itemRenderer)被剪切。此外,滾動網格時,屏幕上滾動的每一行都是默認的文本行高度,無論數據如何。在任何情況下,調整AdvancedDataGrid的大小(不調整其列的大小,但網格本身)會強制所有行捕捉到正確的所需高度。再次滾動會產生不合適大小的行。

此外,行中每個實體的佈局由幾個外部因素決定 - 最常見的是可見範圍(沿水平方向)。更改此可見範圍將觸發所有項呈示器將其自身(通過自定義佈局類)調整爲新的大小並重新測量新的DataGroup佈局。這實際上觸發了一個自定義層次結構分析器,它重新構建了AdvandedDataGrid數據提供者內部使用的所有ArrayCollections,因此ArrayCollections調度每個行的DataGroup對之作出反應的更改事件,因此DataGroup本身將使其大小和佈局無效。

這些大小不會觸發AdvancedDataGrid重新測量其行高,我必須重新調整ADG本身再次將行對齊到正確的高度。

任何人都有使用AdvancedDataGrid或ItemRenderers中的動態大小的行的任何經驗,必須強制使AdvandedDataGrid重新佈局其行?

不幸的是,我無法提供源代碼,因爲有大量的類進入這個層次數據,將封閉節點捲成多行,自定義層次結構解析器,大量項目渲染器 - 以及它的政府合同。

我遇到了一個類似的問題,用一個更簡單的項目渲染器,基本上是一個尊重最大高度的標籤,將其自身的尺寸調整爲其包裝數據所需的高度,然後爲自己創建滾動條。同樣,當網格被創建時,數據大小几乎相同,然後當項目渲染器調整到其新寬度時,更改網格內的列寬並不會調整行高。只有在調整網格大小時,項目渲染器才能正確調整大小,創建滾動條,並且網格行高度正確。該項目渲染器的來源:

<s:Scroller xmlns:fx="http://ns.adobe.com/mxml/2009" 
      xmlns:s="library://ns.adobe.com/flex/spark" 
      xmlns:mx="library://ns.adobe.com/flex/mx" 
      implements="mx.controls.listClasses.IDropInListItemRenderer,mx.controls.listClasses.IListItemRenderer" 
      horizontalScrollPolicy="off" width="100%"> 
    <fx:Script> 
     <![CDATA[ 

      import mx.controls.listClasses.BaseListData; 
      import mx.controls.listClasses.IDropInListItemRenderer; 
      import mx.controls.listClasses.IListItemRenderer; 
      import mx.events.ResizeEvent; 


      private var _listData:BaseListData; 
      private var _data:Object; 

      private var _listOrData_c:Boolean = false; 

      public function get listData():BaseListData 
      { 
       return _listData; 
      } 
      public function set listData(value:BaseListData):void 
      { 
       _listData = value; 
       _listOrData_c = true; 
       invalidateProperties(); 
      } 

      public function get data():Object 
      { 
       return _data 
      } 
      public function set data(value:Object):void 
      { 
       _data = value; 
       _listOrData_c = true; 
       invalidateProperties(); 
      } 

      override protected function commitProperties():void 
      { 
       if(_listOrData_c) 
       { 
        _listOrData_c = false; 
        label.text = _listData.label; 
       } 

       super.commitProperties(); 
      } 

     ]]> 
    </fx:Script> 
    <fx:Declarations> 
     <!-- Place non-visual elements (e.g., services, value objects) here --> 
    </fx:Declarations> 
    <s:Group width="100%"> 
     <s:layout> 
      <s:BasicLayout clipAndEnableScrolling="true" /> 
     </s:layout> 
     <s:Label id="label" width="100%"/> 
    </s:Group> 
</s:Scroller> 

將其投入到AdvancedDataGrid中,並設置一些數據與非常大的文本塊。調整欄大小,然後調整網格本身的大小,希望你可以重現相同的結果。請確保您在項目渲染器上設置最大高度,如:

  <mx:AdvancedDataGridColumn id="adgc1" headerText="Name" dataField="label"> 
       <mx:itemRenderer> 
        <fx:Component> 
         <newLayouts:ScrollingTextItemRenderer maxHeight="60" /> 
        </fx:Component> 
       </mx:itemRenderer> 
      </mx:AdvancedDataGridColumn> 

使用Flex 4.1。

感謝您的幫助。

下面是屏幕截圖,詳細的項目渲染器,因爲它應有的功能(如我有固定的測量在測量之前在明確的當前寬度強行驗證標籤):

非常寬列,沒有滾動條,標籤測得的高度以行高度 enter image description here

較小寬度柱,一些渲染器擊中最大高度示出並正在創建滾動條,最後的渲染器仍使用標籤的測量高度 enter image description here

更小的靜止列,所有最大高度都會打中,並且所有標籤都顯示滾動條,滾動條將在使用時選擇該行,但允許滾動以便所有文本均可查看。 enter image description here

+0

是否有可能被切斷的那個需要比上面指定的60 px maxHeight更高? –

+0

如果標籤需要更高,那麼滾動條會產生滾動條,這是所需的行爲。只是滾動條本身不會調整大小,高級數據網格行也不會正確調整大小,直到ADG的大小發生變化。 – David

+0

基於MX列表的組件的問題的一部分是它們設置了explicitHeight/explicitWidth,而不是高度和寬度,這不會觸發measure()。但是,您正在使用Scroller,即使Measure()方法確實被調用,我也不確定Scroller在這種情況下如何處理測量。我建議在explictWidth/explictHeight中調用invalidateSize(),並重寫measure()來處理組件的需求。 –

回答

2

今天上午經過仔細檢查後,DataGroup渲染器的meausre方法本身並沒有正確地驗證第一次測量通過時其子項的大小。

我需要這些項目中的標籤有一個限制寬度,所以他們將wordwrap適當,所以當我測量DataGroup行時,我需要設置其每個孩子的寬度,然後衡量孩子。問題是validateSize()沒有正確地驗證元素的大小(標籤沒有被更新並在此時生成新的文本行)。所有後續的測量通過已經有一個寬度驗證給每個孩子,所以再次測量他們是正確的。因此,在調整網格大小時,後續的度量調用起作用。

我採取強行驗證DataGroup的度量方法內的每個孩子,正確的高度現在正在返回,因此AdvancedDataGrid現在正在acacally調整行的大小。

這可能效率很低,因爲每個項目現在每次生命週期通過兩次驗證,但網格按照期望執行。

可能與ScrollingLabelItemRenderer類似,與第一次測量自身時由於標籤可能沒有得到寬度驗證一樣,因此設置了網格接受並用作行高度的錯誤測量大小。

我現在再次正確運行ScrollingLabelItemRenderer,我不得不強制將寬度應用於標籤並在測量渲染器時對其進行驗證,因爲在應用新寬度之前,仍然使用其先前的寬度和文本行進行測量後續updateDisplayList ...

 override protected function measure():void 
     { 
      label.width = getExplicitOrMeasuredWidth() - verticalScrollBar.getExplicitOrMeasuredWidth(); 
      label.validateNow(); 
      super.measure(); 
     } 
0

我已經花了幾個星期的時間試圖讓MX AdvancedDataGrid正確處理變量的行高,錯誤沒有真正成功。有些情況下高度不正確。所有這些都是關於調用網格渲染器重新佈局,這是一個非常漫長的操作,使得項目非常緩慢。

我建議你移動到Spark AdvancedDataGrid這是基於Spark DataGrid工程複雜renderers快得多。