我在屏幕上有2个flex datagrids。用户可以从任一数据网格中选择一行或多行,并将它们移动到另一个数据网格。进入应用程序时,下表为空。例如:
Item Color Price
--------------------
item57 red $5.55
item62 blue $5.29
item808 green $2.21
Row Item Color Price
---------------------------
请注意,有一列对底部数据网格中的行进行编号(仅限)。
当我进入应用程序并移动时,例如,从顶部到底部网格移动3行,行号很好(它们显示行1,2和3)。例如:
Item Color Price
--------------------
Row Item Color Price
---------------------------
1 item57 red $5.55
2 item62 blue $5.29
3 item808 green $2.21
如果我然后移动,例如,底部网格中的第1行返回顶部...
Item Color Price
--------------------
item57 red $5.55
Row Item Color Price
---------------------------
1 item62 blue $5.29
2 item808 green $2.21
然后再回到底部网格......
Item Color Price
--------------------
Row Item Color Price
---------------------------
1 item62 blue $5.29
2 item808 green $2.21
1 item57 red $5.55
行号应该显示为3,因为它插入到列表末尾的底部网格中,但是当它执行此操作时,它会显示(旧)行号值为1。
当我调试并查看dataprovider = _myData时,我看到有问题的行的rowNumber
值(对于上面的item57)等于3(应该如此)。但是,它在下部数据网格中显示为1。
dataprovider值如何与DataGrid中显示的值不同?
[我还可以调试并查看gridLower
列信息,并为相关数据显示rowNumber
的正确值3。]
下层数据网格类似于以下内容(虽然我使用的是自定义itemRenderer,为简单起见,此处已删除):
[Bindable]
private var _myData:ListCollectionView=new ListCollectionView(new ArrayList());
...
<s:DataGrid dataProvider="{_myData}">
<s:columns>
<fx:Array>
<s:GridColumn id="gridLower" headerText="myHeader" dataField="rowNumber"/>
...
将上表的行添加到下表的函数是:
private function addRow():void {
var selectedIndices:Object=gridUpper.grid.selectedIndices;
for (var i:int=selectedIndices.length-1;i>=0;i--) {
var item:Object=_upperTableData.removeItemAt(selectedIndices[i]);
item.rowNumber=_myData.length+1;
_myData.list.addItem(item);
}
// I tried adding "_myData.refresh();" here and it had no effect
// I tried adding "ListCollectionView(gridLower.dataProvider).refresh();" and it had no effect
// I tried adding "grid2.dataProvider.refresh();" here but it had no effect
}
更新1:如果我对下表中的任何列重新排序,则会显示正确的值。我似乎在观察此链接中的报告:
http://www.barneyb.com/barneyblog/2007/06/23/another-flex-weirdnessgotcha/
但是还没有找到解决方案。在上面的addRow()
函数中查看尝试次数。我是在正确的轨道上吗?
更新2:虽然重新排序手动纠正较低网格中的数据,但我还没有找到以编程方式执行此操作的方法。我试着插入:
_myData.sort=null;
var complete:Boolean=_myData.refresh();
就在上面的addRow()
函数结束之前,但它没有解决我的问题。调试时,complete
为真,但下面的网格仍显示过时数据。
答案 0 :(得分:1)
新答案:)如果有帮助,我会删除旧的。
我还没有使用Spark DataGrid,期望它的行为像List。
在DataGrid的这个方法的源代码中的一些注释中找到了这个:
public function invalidateCell(rowIndex:int, columnIndex:int):void
您可以通过为另一个值传递-1来使整个行/列无效。在下面文档的引用中,您还可以使用dataProvider.itemUpdated()
如果指定的单元格可见,则会重新显示该单元格。如果 variableRowHeight = true,然后这样做可能会导致高度 相应的行要改变。如果columnIndex为-1,则为整行 无效。同样,如果rowIndex为-1,则整个列为 无效。
当任何方面发生变化时,应该调用此方法 rowIndex中的数据提供程序项可能会对其产生一些影响 显示指定单元格的方式。调用此方法类似于 调用dataProvider.itemUpdated()方法,该方法建议Grid 显示指定项目的所有行都应重新显示。 使用这种方法可以相对有效,因为它缩小了 单个单元格的更改范围。
现在我终于知道了集合(ArrayCollection,ListCollectionView)上的itemUpdated()方法实际可以在哪里使用了!
[编辑]
为您的网格指定一个ID:
<s:DataGrid id="lowerDataGrid" dataProvider="{_myData}">
然后,您应该可以在更新集合后使用addRow()
方法执行此操作:
lowerDataGrid.invalidateCell(item.rowNmber -1, 1); // assuming rowNumbers are 0 based
答案 1 :(得分:0)
在我的情况下,在我的主类中包含网格作为元素,每当我想强制刷新所有单元格时:
gridsDataProvider.addItemAt(new Object(), 0);
gridsDataProvider.removeItemAt(0);
但是我的GridItemRenderer需要满足数据的变化。所以我创建了一个updateDisplay方法:
private function updateDisplay() : void {
if (transWindow != null) {
if (data == transWindow.total) {
if (field != "vat" && field != "total") {
textInput.visible = false;
} else {
line.visible = true;
textInput.enabled = false;
textInput.setStyle("fontWeight", "bold");
textInput.setStyle("fontSize", 14);
}
} else {
line.visible = false;
textInput.visible = true;
textInput.enabled = true;
textInput.setStyle("fontWeight", "normal");
textInput.setStyle("fontSize", 12);
}
}
}
从creationComplete处理程序...
调用此方法 protected function init(event:FlexEvent):void
{
getTransWindow(event.target.automationOwner);
updateDisplay();
}
......以及GridItemRenderer的数据设定者
override public function set data(v:Object):void {
super.data = v;
if (v == null) {
textInput.text = "";
return;
}
var value : * = v[field];
if (value == null || value == undefined) {
textInput.text = "";
return;
}
if (value is Number)
textInput.text = Number(value).toFixed(2);
else
textInput.text = ""+value;
updateDisplay();
}
我的渲染器的mxml主体非常简单:
<s:Line id="line" width="100%" visible="false" yFrom="1" yTo="1">
<s:stroke>
<s:SolidColorStroke color="0" weight="0"/>
</s:stroke>
</s:Line>
<s:TextInput id="textInput" y="2" restrict="0123456789." width="100%" height="100%" minWidth="10" borderVisible="false" textAlign="right"/>
O,如果你想知道,getTransWindow方法只是一个检索包含网格的主调用类的方法:
private function getTransWindow(par : *) : void {
if (transWindow != null)
return;
transWindow = par;
while (!(transWindow is TransactionWindow)) {
transWindow = transWindow.parent;
}
}
希望这能节省一些时间
此致 克里斯托