我有一个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。
感谢您的帮助。
以下是详细介绍项目渲染器的截图,因为它应该起作用(因为我已经修复了测量,以便在测量前以显式当前宽度强制验证标签):
非常宽的列,没有滚动条,标签测量的高度显示在行高
较小的宽度列,一些渲染器已达到最大高度并且正在创建滚动条,最后一个渲染器仍在使用标签的测量高度
较小的静止列,所有最大高度都被命中,所有标签都有滚动条,滚动条将在使用时选择行但允许滚动以便所有文本都可见。
答案 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}},并对复杂的渲染器更快地运行。