在将mx:AdvanceDataGrid转换为s:DataGrid时,我的变量行高会导致我的DataGrid的高度计算不正确。我试图在不使用滚动条的情况下显示所有行。
此图像显示不正确的高度(最后一行被切断):
当行的大小增加时会出现问题,例如,为了适应自动换行,导致行与typicalItem的大小不同。当我的项目使用mx:AdvanceDataGrid时,我们使用此代码https://stackoverflow.com/a/1889005使用此处列出的measureHeightOfItems()方法来解决此问题:
private function calculateTableHeight():void
{
var tableHeightPixelHack:Number = 30;
var numRows:Number = dataGrid.dataProvider != null ? dataGrid.dataProvider.length : 0;
tableHeight = dataGrid.measureHeightOfItems(-1, numRows) + tableHeightPixelHack;
}
我的问题是,如何在s:DataGrid中实现相同的结果,就像我在mx:AdvanceDataGrid上使用measureHeightOfItems方法一样?
s:DataGrid组件
<s:DataGrid id="dataGrid"
width="100%"
columns="{hostComponent.columns}"
dataProvider="{hostComponent.data}"
selectionMode="singleRow"
sortableColumns="false"
styleName="goalsDataGrid"
variableRowHeight="true"
verticalScrollPolicy="off"
horizontalScrollPolicy="off"
doubleClickEnabled="true"
/>
自定义项呈示器(通过代码分配)
<?xml version="1.0" encoding="utf-8"?>
<s:GridItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
focusEnabled="true">
<s:Rect top="0" bottom="0" right="0" left="0" z="-1">
<s:fill>
<s:SolidColor color="{data.rowColor}"/>
</s:fill>
</s:Rect>
<s:Label id="lblData"
styleName="tableRow"
text="{label}"
width="100%"
height="100%"
maxDisplayedLines="-1"
lineBreak="toFit" />
</s:GridItemRenderer>
答案 0 :(得分:0)
在DataGrid中设置verticalScrollPolicy =“auto”
答案 1 :(得分:0)
对于 Spark DataGrid
,您可以计算DataGrid
的高度,如下所示:
private function calculateTableHeight():void
{
var totalHeight:Number = 0;
for (var row:int = 0; row < dataGrid.dataProvider.length; row++) {
var renderer:IGridItemRenderer = dataGrid.grid.getItemRendererAt(row,1);
if (renderer){
totalHeight += renderer.height;
}
}
dataGrid.height = totalHeight + dataGrid.columnHeaderGroup.height + 2;
}
以下是一个示例应用:
<?xml version="1.0"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
updateComplete="sizeDGExactly()"
width="100%"
height="100%">
<fx:Script><![CDATA[
import mx.collections.ArrayCollection;
import spark.components.gridClasses.IGridItemRenderer;
[Bindable]
private var notes:ArrayCollection = new ArrayCollection([
{who: 'Bikram', note_txt: 'ActionScript 3 has empowered Flash developers with faster code execution and a ton of API enhancements.Last line.'},
{who: 'Anup', note_txt: 'Unfortunately, it has also led to the need for a much higher level of developer responsibility than ever before. ' +
'In order to prepare and educate developers on how to deal with some of this new responsibility, \n\nI am writing a series of articles on resource ' +
'management in AS3, Flex 2, and Flash 9. \n\nThe first of these articles discussed the mechanics of the Garbage Collector in Flash Player 9. ' +
'This article will focus on the implications some of the new features of AS3 have on resource management, and the potential headaches they could ' +
'cause you even in simple projects. \n\nThe next article in the series will introduce some of the new tools we have at our disposal to deal with these issues.Last line.'},
{who: 'Mark', note_txt: 'The biggest change in AS3 that affects resource management is the new display list model. In Flash Player 8 and below, ' +
'when a display object was removed from the screen (with removeMovie or unloadMovie), it and all of its descendants were immediately removed from ' +
'memory, and halted all code execution.Last line.'},
{who: 'George', note_txt: 'It is very important to note that not only will the display object continue to use memory, it will also continue to ' +
'execute any “idle” code, such as Timers, enterFrames, and listeners outside its scope. A couple of examples may help illustrate this issue:'+
'You have a game sprite that subscribes to its own enterFrame event. Every frame it moves and carries out some calculations to determine ' +
'it’s proximity to other game elements. In AS3, even after you remove it from the display list and null all references to it, it will continue ' +
'to run that code every frame until it is removed by garbage collection. You must remember to explicitly remove the enterFrame listener when the sprite ' +
'is removed.\n\n'+
'Consider a MovieClip that follows the mouse by subscribing to the stage’s mouseMove event (which is the only way to achieve this effect in ' +
'the new event model). Unless you remember to remove the listener, the clip will continue to execute code every time the mouse is moved, even after ' +
'the clip is “deleted”. By default, the clip will execute forever, as a reference to it exists from the stage for event dispatch (we will look at ' +
'how to avoid this in the next article).\n\n'+
'Now imagine the implications of instantiating and removing a bunch of sprites before the GC does a sweep, or if you failed to remove all references. ' +
'You could inadvertently max out the CPU fairly easily, slowing your application or game to a crawl, or even stalling the users’ computers entirely. ' +
'There is NO WAY to force the Flash Player to kill a display object and stop it executing. You must do this manually when it is removed from the display. ' +
'I will examine strategies to manage this task in a future article.\n\n'+
'Here\’s a simple example (Flash Player 9 required). Click the “create” button to create a new Sprite instance. The sprite instance will start ' +
'outputting a counter. Click remove and note how the output continues, despite the fact that all references to the sprite have been nulled. You can create ' +
'multiple instances to see how this issue compounds over the life of an application. Source code is available at the end of this article. Last line.'}
]);
private function sizeDGExactly():void
{
if (notesDataGrid)
{
var totalHeight:Number = 0;
for (var row:int = 0; row < notesDataGrid.dataProvider.length; row++) {
var renderer:IGridItemRenderer = notesDataGrid.grid.getItemRendererAt(row,1);
if (renderer){
totalHeight += renderer.height;
}
}
notesDataGrid.height = totalHeight + notesDataGrid.columnHeaderGroup.height + 2;
}
}
public function onDeleteButtonClick(item:Object):void
{
notes.removeItemAt(notes.getItemIndex(item));
sizeDGExactly();
}
]]></fx:Script>
<s:Scroller width="100%" height="100%"
left="10" right="10" top="10" bottom="10"
horizontalScrollPolicy="off" verticalScrollPolicy="auto">
<s:VGroup width="100%" height="100%">
<s:Group width="100%">
<s:Panel title="Empty Top Panel" width="50%" horizontalCenter="0">
<s:Label text="This is just an additional component in the layout." width="100%"/>
</s:Panel>
</s:Group >
<s:HGroup width="100%">
</s:HGroup>
<s:HGroup width="100%">
<s:DataGrid id="notesDataGrid"
verticalCenter="0"
width="100%"
dataProvider="{notes}"
sortableColumns="false"
variableRowHeight="true">
<s:columns>
<s:ArrayList>
<s:GridColumn width="200"
headerText="Who Noted"
dataField="who"/>
<s:GridColumn dataField="note_txt"
headerText="Note">
<s:itemRenderer>
<fx:Component>
<s:GridItemRenderer>
<s:Label width="100%" height="100%" text="{data.note_txt}"
paddingTop="10"
paddingBottom="10"
paddingLeft="10"
paddingRight="10"/>
</s:GridItemRenderer>
</fx:Component>
</s:itemRenderer>
</s:GridColumn>
<s:GridColumn width="70">
<s:itemRenderer>
<fx:Component>
<s:GridItemRenderer>
<s:Button width="60" height="20" label="Delete"
horizontalCenter="0" verticalCenter="0"
click="outerDocument.onDeleteButtonClick(data)"/>
</s:GridItemRenderer>
</fx:Component>
</s:itemRenderer>
</s:GridColumn>
</s:ArrayList>
</s:columns>
</s:DataGrid>
</s:HGroup>
<s:Group width="100%">
<s:Panel title="Empty Bottom Panel" width="50%" horizontalCenter="0">
<s:Label text="This is just an additional component in the layout." width="100%"/>
</s:Panel>
</s:Group>
</s:VGroup>
</s:Scroller>
</s:Application>