0

我在屏幕上有 2 个 flex 数据网格。用户可以从任一数据网格中选择一个或多个行并将它们移动到另一个数据网格。进入应用程序时,下方表格为空。例如:

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为真,但下方网格仍显示陈旧数据。

4

2 回答 2

1

新答案:) 如果有帮助,我将删除旧答案。

我还没有使用过 Spark DataGrid,期待它的行为像一个列表。

在此 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
于 2012-05-08T22:09:26.897 回答
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"/>

哦,如果您想知道,getTransWindow 方法只是一种检索包含网格的主调用类的方法:

private function getTransWindow(par : *) : void {
            if (transWindow != null)
                return;
            transWindow = par;
            while (!(transWindow is TransactionWindow)) {
                transWindow = transWindow.parent;
            }
        }

希望这可以节省一些时间

问候克里斯托

于 2014-02-09T15:48:03.497 回答