2011-09-14 4 views
1

変数行の高さがtrueに設定されたAdvancedDataGridがあります。 データグループのスパークコンポーネントに基づいてcutsomアイテムレンダラーを作成しました。グリッドの各行には表示する複数のエンティティがあり、エンティティのx位置と幅はエンティティ自体のデータに基づいています。ItemRendererの高さ(および高さの変更)がAdvancedDataGrid行に反映されない

私は、データに基づいて各エンティティを測定して位置付けるDataGroup用に作成されたカスタムレイアウトを持っています。各行の各エンティティは、ラベルを切り捨てるか、または切り捨てることができます。ラベルが切り捨てられていないときは、オブジェクトの実際の幅を計算し、そのサイズを手動で検証します(ラベルを正しい幅にして、すべてのテキスト行とレイアウトを再レイアウトする)データグループ自体。

レイアウト、測定、サイジング、表示などはすべて正しく動作します。エンティティは、ラベルを切り捨てないときに必要な正確な高さを報告し、datagroupは行のすべてのエンティティを描画するのに必要な正しいサイズを報告します(すべてUIComponentライフサイクルの必要な測定方法から)。

AdvancedDataGrid自体の内部では、行のサイズが正しく設定されていません。大部分の行は複数の行を必要とせず、うまく表示できます。複数の行を必要とする行は、行の高さが大きくなりますが、ほとんどの場合、テキスト全体を収容するのに十分な大きさではありません。その行(およびそのitemRenderers)のデータグループがクリップされます。さらに、グリッドをスクロールすると、画面にスクロールされるすべての行は、データに関係なく、デフォルトの1テキスト行の高さになります。いずれにせよ、AdvancedDataGrid(列のサイズは変更せず、グリッド自体)のサイズを変更すると、すべての行が正しい高さに合わせられます。再度スクロールすると、大変なサイズの行が生成されます。

さらに、行内の各エンティティのレイアウトは、いくつかの外部要因によって決定されます。最も一般的には、表示範囲(水平方向)です。この可視範囲を変更すると、すべてのアイテムレンダラーがカスタムレイアウトクラスを使用して新しいサイズにサイズ変更され、新しいデータグループレイアウトが再測定されます。これにより、実際にAdvandedDataGridデータプロバイダ内で使用されるすべてのArrayCollectionを再構築するカスタム階層パーサがトリガされるため、ArrayCollectionsは各行のDataGroupが対応する変更イベントを送出しているため、DataGroup自体がサイズとレイアウトを無効にします。

これらのサイズ変更では、行の高さを再測定するためにAdvancedDataGridがトリガーされません。また、正しい高さに行をスナップするには、再度ADGを再調整する必要があります。

アドバンストデータグリッドまたはItemRenderers内の誰かが、アドバンストデータグリッドの行を再レイアウトするように強制しなければならないことがあります。

残念ながら、膨大な数のクラス、階層データ、クローズドノードを複数の行に振り分けること、カスタム階層パーサー、多数のアイテムレンダラー - と政府契約があるため、私はソースコードを提供できません。

私は非常に単純なアイテムレンダラー、基本的には最大高さを尊重し、ワードラッピングデータに必要な高さまでサイズを変更してから、それ自体のスクロールバーを作成するというラベルを付けました。グリッドが作成されたときのデータサイズはほとんど同じですが、グリッド内の列幅を変更しても、アイテムレンダラーが新しい幅に調整されるため、行の高さは変更されません。グリッド自体のサイズ変更でのみ、アイテムレンダラーが正しくサイズ変更され、スクロールバーが作成され、グリッドの行の高さが正しくなります。そのアイテムレンダラーのソース:

<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ピクセルmaxHeightよりも大きい必要がありますか? –

+0

ラベルの背を高くする必要がある場合は、スクロールバーがスクロールバーを生成します。これが望ましい動作です。 ADGのサイズが変更されるまで、スクロール自体のサイズ変更や高度なデータグリッド行のサイズ変更は行われません。 – David

+0

MXリストベースコンポーネントの問題の一部は、measure()をトリガーしないheightとwidthではなく、explicitHeight/explicitWidthを設定することです。しかし、あなたはScrollerを使っていますが、measure()メソッドが呼び出されてもこの状況での測定をScrollerがどれくらいうまく準備しているかわかりません。 explictWidth/explictHeightでinvalidateSize()を呼び出し、コンポーネントのニーズを処理するためにmeasure()をオーバーライドすることをお勧めします。 –

答えて

2

今朝の検査の結果、DataGroupレンダラ自体のメーザー法では、最初の小節通過時に子どものサイズが正当であるとは限りませんでした。

これらの項目にはラベルが必要なため、適切に単語を折り返すようにする必要があります。そのため、データグループの行を測定しているときに、それぞれの子の幅を設定し、子を測定する必要があります。問題はvalidateSize()が要素のサイズを正しく検証していない(ラベルが更新されず、この時点で新しいテキスト行を生成していた)その後の測定パスはすべて、すでに各子に検証された幅を持っていたので、再度測定するのは正しいものでした。グリッドのサイズを変更すると、その後のメジャーコールが機能しました。

データグループのメジャーメソッド内で各子を強制的に検証して、正しい高さが返されていたため、AdvancedDataGridはその行を今度は正確にサイズ変更しています。

これは、各アイテムがライフサイクルパスごとに2回検証されるが、グリッドは必要に応じて実行されるので、これはむしろ非効率的なことがあります。

恐らく、ScrollingLabelItemRendererで起こりそうなことは、ラベルが最初に測定したときにその幅が検証されないため、グリッドが受け入れて行の高さとして使用する間違った測定サイズを設定するためです。

私はScrollingLabelItemRendererを正しく機能させました。ラベルに幅を強制的に適用して、レンダラーを測定するときにそれを検証しなければなりませんでした。その後のupdateDisplayList ...

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

私はMX AdvancedDataGridが可変行の高さを正しく処理できるようにしようとしましたが、バグは本当にうまくいかなかったのです。高さが正しくない場合が常にあります。これは、グリッドレンダラーの再レイアウトを呼び出すことに関するもので、非常に長い操作であり、プロジェクトが非常に遅くなります。

は、私はあなたがSpark DataGridに基づいており、複雑なレンダラーのためにはるかに高速を動作しますSpark AdvancedDataGridに移動することをお勧めします。

関連する問題