4


3

Flex - 自動サイズ変更データグリッドの問題

すべてのレンダラーが完全に表示されるように、縦方向にサイズ変更するデータグリッドを作成しようとしています。 さらに、

  • レンダラーは高さが可変です

  • レンダラーは自分のサイズを変更できます

一般的に言えば、イベントの流れは次のとおりです。

  • アイテムレンダラーの1つがそれ自体のサイズを変更します(通常、 ユーザークリックなど)

  • それは、親データグリッドが拾うバブルイベントを送出します。

  • DataGridは、すべてのレンダラーが残るようにサイズを変更しようとします 完全に見える。

現在、高さを計算するためにデータグリッド内でこのコードを使用しています。

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

これは不正確な高さになるようです。 callLater(サイズ変更が完了したことを確認して、正しく機能するようにする)、およびmeausre()のオーバーライド、invalidateSize()/ validateSize()の呼び出しなど、さまざまな方法を試しましたが、どちらも機能しません。

以下は、問題を説明する3つのクラスです。 アイテムレンダラーのボタンをクリックすると、レンダラーのサイズが変更されます。 また、3つのレンダラーがすべて全体として表示されるように、グリッドも拡張する必要があります。

任意の提案は大歓迎です。

よろしく

マーティ

  • DataGridProblem.mxml(アプリケーションファイル)*

        Item A
        Item B
        Item C
  • 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 *

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

9 Answer


2


次のコードを使用してAdvancedDataGridでこの目的を達成できます。 this.headerHeightを削除すると、Listでも機能します。これは、通常の古いDataGridでも機能するはずだと私に信じています。

保護されている関数measure()をオーバーライドします。void {super.measure();}

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

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


1


実行時にデータグリッドのサイズを変更するには…​ rowcountプロパティを使用してdataproviderの長さにバインドします。 データプロバイダが更新されると、行数も更新されます。 あなたはflexでrowcountを使用する方法の例を見ることができます here


0


幅や高さが可変のセル/行/列、その他の「高度な」機能などをするには、古い、つまらない DataGrid`ではなく AdvancedDataGrid`を拡張してみてください。


0


それが価値があるもののために、私はこの問題を解決することができなかった。 コードはすぐにエッジケースを扱うことに夢中になりました。

私はdataGridアプローチを捨て去り、VBoxを使った解決策を書きました。


0


その価値のために。 datagrid / advanced datagridのvariableRowHeight = "true"プロパティを使うことになっていました。

それがあなたが気分を良くさせるのであれば私はカスタムVBox、HBoxのソリューションを作成し、その後それはすでにそれが行われていることを発見! (スナップ!!)

がんばろう!


0


あなたのアプローチには根本的な問題があります。 ItemRenderersはデータ項目を一貫した方法でレンダリングすることを目的としています。現在のレンダラーを破棄して新しいレンダラーを作成し、その新しいレンダラーのdataプロパティを設定すると、前のレンダラーと同じになります。 データメンバの外側でレンダラーに一時的な変更を加えることは想定されていません。その場合、レンダラーは奇妙な方法で動作します。

countプロパティを含むようにデータモデルオブジェクトを変更し、レンダラーの高さを式 "\ {50 data.count * 20}"にデータバインドした後、ボタンのクリックハンドラでdata.countを1だけ増加させるとします。これは正しく機能するでしょう。 (私の経験では、dataGridがmakeRowsAndColumns()を呼び出す前に、dataプロパティの結果として変更が行われる限り、DataGridは各行に適切なサイズで自分自身を再描画します。 私はあなたの例のためにそのアプローチを試したことがないので、私はそれが実際にうまくいくと確信することはできませんが、確かにそれはアイテムレンダラーを扱うための正しい考え方です。


0


私はこのような問題のための少し汚れた解決策がありますこれを試してみてください

プライベート関数ResizeGrid():void {if(this.dg.maxVerticalScrollPosition> 0){this.dg.height = 5; setTimeout(this.ResizeGrid、100); }}

そして、次のように少し遅れて関数を呼び出します。

setTimeout(this.ResizeGrid、100);

これは汚いアプローチですが、それは私のために働く:)


0


次の `gridItemRenderer`のコードは役に立ちました:

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


0


私はこの問題に対する解決策を持っています、レンダラの変更はあなたのデータプロバイダと同期する必要があります。 その後、measureHeightOfItemsメソッドのみが正確な結果を返します。