ItemRenderer高度(和高度更改)未反映在AdvancedDataGrid行中

时间:2011-09-14 19:31:15

标签: flex actionscript itemrenderer advanceddatagrid

我有一个AdvancedDataGrid,其变量行高设置为true。 我已经根据DataGroup spark组件编写了一个cutom项目渲染器。网格中的每一行都有多个要显示的实体,entites的x位置和宽度基于实体本身的数据。

我为DataGroup编写了一个自定义布局,根据其数据测量和定位每个实体。每行中的每个实体都可以截断或不截断其标签。当标签没有被截断时,我计算对象的实际宽度并手动验证其大小(以强制标签具有正确的宽度和布局所有文本行并重新测量自身)在DataGroup的布局测量方法中准确测量数据组本身。

布局,测量,尺寸,显示等都能正常工作。实体在不截断标签时报告所需的正确高度,数据组报告绘制其所有行的实体所需的正确大小(所有这些都来自测量方法,如他们在UIComponent生命周期下所需)。

在AdvancedDataGrid本身内部时,行的大小不正确。大多数行不需要多行并且显示得很好。那些需要多行的行具有较大的行高,但在大多数情况下不足以容纳整个文本。该行的DataGroup(及其itemRenderers)被剪裁。此外,滚动网格时,屏幕上滚动的每一行都是默认的1文本行高,无论数据如何。在任何情况下,调整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

2 个答案:

答案 0 :(得分:2)

在今天早上进行了更仔细的检查之后,DataGroup渲染器本身的meausre方法并没有在第一次测量通过时验证其子节点的大小。

我需要这些项目中的标签具有有限的宽度,以便它们适当地进行自动换行,因此当我测量DataGroup行时,我需要设置每个子项的宽度,然后测量子项。问题是validateSize()没有正确验证元素大小(标签没有被更新并且此时生成了新的文本行)。所有后续测量通过已经为每个孩子验证了宽度,因此再次测量它们是正确的。因此,在调整网格大小时,后续的度量调用会起作用。

我在DataGroup的measure方法中强制验证每个子节点,现在正在返回正确的高度,因此AdvancedDataGrid现在正在调整其行的大小。

这可能相当低效,因为现在每个生命周期传递都会对每个项目进行两次验证,但网格正在按预期执行。

ScrollingLabelItemRenderer可能会发生类似的情况,因为当第一次测量自身时,标签可能无法验证其宽度,从而设置网格接受并用作行高的错误测量尺寸。

我现在让ScrollingLabelItemRenderer再次正常工作,我不得不强制在标签上应用宽度并在测量渲染器时对其进行验证,因为在测量之前它仍在使用其先前的宽度和文本行,然后再应用新的宽度updateDisplayList ...

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

答案 1 :(得分:0)

我花了几周的时间试图让MX AdvancedDataGrid正确处理变量行高,但错误并没有真正成功。总有一些情况下高度不正确。所有这些都是关于调用网格渲染器重新布局,这是一个非常长的操作,使得项目非常缓慢。

我建议您转到基于Spark DataGrid的{​​{3}},并对复杂的渲染器更快地运行