【问题标题】:Flex - Problem with auto resizing datagridFlex - 自动调整数据网格大小的问题
【发布时间】:2010-10-11 05:33:44
【问题描述】:

我正在尝试创建一个数据网格,它将垂直调整大小以确保所有渲染器都完整显示。此外,

  • 渲染器的高度可变
  • 渲染器可以自行调整大小

一般来说,事件的流程如下:

  • 其中一个项目渲染器会自行调整大小(通常响应用户点击等)
  • 它调度父数据网格接收的冒泡事件
  • DataGrid 尝试调整大小以确保所有渲染器保持完整可见。

我目前在数据网格中使用此代码来计算高度:

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

这似乎得到了不正确的高度。我尝试了许多变体,包括 callLater(以确保调整大小已完成,以便测量可以正常工作),以及覆盖 meausre() 和调用 invalidateSize() / validateSize(),但都不起作用。

下面是 3 个类来说明这个问题。单击项目渲染器中的按钮会调整渲染器的大小。网格也应该展开,以便完整显示所有 3 个渲染器。

任何建议将不胜感激。

问候

马蒂

DataGridProblem.mxml(应用程序文件)

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

【问题讨论】:

    标签: apache-flex


    【解决方案1】:

    要做诸如可变宽度和高度单元格/行/列之类的事情,以及其他“高级”功能 - 尝试扩展 AdvancedDataGrid 而不是旧的、更无聊的 DataGrid

    【讨论】:

    • 您好 在这种情况下,不能选择使用 AdvancedDataGrid。问候马蒂
    • “无聊”我想你的意思是“少车”。
    【解决方案2】:

    不管怎样,我从来没有设法解决这个问题。代码很快就沉迷于处理边缘情况。

    我最终放弃了 dataGrid 方法,并使用 VBox 和 HBox 编写了一个解决方案以方便调整大小。

    【讨论】:

      【解决方案3】:

      因为它的价值;你应该使用数据网格/高级数据网格的 variableRowHeight="true" 属性。

      如果它让您感觉更好,我创建了自定义 VBox、HBox 解决方案,然后发现它已经完成了!! (啪!!)

      祝你好运!

      【讨论】:

      • 嗨,Vusi,我已经尝试过使用 variableRowWidth=true,但它并没有解决问题(您现在似乎面临)
      【解决方案4】:

      您的方法存在潜在问题。 ItemRenderers 旨在以一致的方式渲染数据项,如果您丢弃当前渲染器并创建一个新渲染器并设置新渲染器的数据属性,它应该看起来与前一个相同。您不应该在数据成员之外对渲染器进行临时更改,并且当您这样做时渲染器会以奇怪的方式运行。

      我怀疑如果您将数据模型对象更改为包含计数属性,并且数据将渲染器的高度绑定到表达式“{50 + data.count * 20}”,然后使按钮的点击处理程序递增 data.count 1,这将正常工作。 (我的经验是,只要在调用 makeRowsAndColumns() 之前由于数据属性而完成更改,DataGrid 就会以每行的适当大小重新绘制自身。)我没有为您的示例尝试过这种方法,所以我不能肯定它确实有效,但肯定是使用项目渲染器的正确心态。

      【讨论】:

        【解决方案5】:

        您可以使用以下代码通过 AdvancedDataGrid 实现此目标。如果删除 this.headerHeight,它也适用于 List,这让我相信它应该适用于常规的旧 DataGrid。

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

        【讨论】:

        • 好东西!这是一个更漂亮的版本:var newHeight:int = measureHeightOfItems(-1, dataProvider.length);
        【解决方案6】:

        要在运行时调整数据网格的大小......使用 rowcount 属性并将其与 dataprovider 长度绑定。随着数据提供者的更新,行数也会更新。
        您可以在 flex here 中查看如何使用 rowcount 的示例

        【讨论】:

          【解决方案7】:

          对于此类问题,我有一些肮脏的解决方案试试这个

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

          然后像下面这样延迟调用你的函数

          setTimeout(this.ResizeGrid,100);
          

          这是一种肮脏的方法,但它对我有用:)

          【讨论】:

            【解决方案8】:

            gridItemRenderer 中的以下代码帮助了我:

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

            【讨论】:

              【解决方案9】:

              我有这个问题的解决方案,渲染器更改需要与您的数据提供者同步。 那么只有 measureHeightOfItems 方法才能给出准确的结果。

              【讨论】:

                猜你喜欢
                • 2017-01-29
                • 1970-01-01
                • 1970-01-01
                • 2017-08-04
                • 1970-01-01
                • 2021-04-05
                • 2014-06-27
                • 1970-01-01
                • 2011-07-14
                相关资源
                最近更新 更多