1

我正在使用火花列表,并希望在更改作为数据提供者的列表内容后保持选择。如果您设置一个新的数据提供者,List 会将其 selectedIndex 设置回 -1。我们通过拦截当 List 想要将自身设置回 -1 并设置先前选择的项目(如果新的数据提供者仍然包含它)时触发的 valueCommit 事件来解决这个问题。到目前为止这有效,但我们得到了奇怪的行为:

  • 最初,先前选择的项目仍被选中并按预期突出显示
  • 如果选择了另一个项目,突出显示将停留在初始项目上。不管我多久选择另一个,初始项目仍然突出显示但未选择。新选择的项目实际上已被选中并突出显示。
  • 如果再次选择初始项目,则列表再次表现正常。当我在重新选择第一个项目后选择另一个项目时,突出显示消失。

List 在 MXML 中声明,如下所示:

<s:List dataProvider="{model.dataProvider}"
selectedIndex="@{model.selectedIndex}"
valueCommit="model.handleInputObjectListValueCommit(event)"/>

模型类中的代码非常复杂,但这应该是相关部分:

[Bindable]
public var dataProvider:ArrayCollection;

[Bindable]
public var selectedIndex:int;

private var _indexToSelect:int = -1;

public function setNewContent(newContent:ArrayCollection):void {

    undoManager.ignore(function ():void {

        dataProvider.removeAll();
        dataProvider.addAll(newContent);

        _indexToSelect = selectedIndex;
    });
}

public function handleValueCommit(event:Event):void {
    if (_indexToSelect != -1) {
        const localIndex:int = _indexToSelect;
        _indexToSelect = -1;
        selectedIndex = localIndex;
    }
}

undManager 是一个负责撤销/重做的类。ignore 函数注意 undoManager 不会将 dataProvider 中的更改注册为可撤消的操作,因为只有用户交互应该是可撤消的。

有任何想法吗?

4

3 回答 3

1

我在捕获更改事件时得到了描述的结果,并且在那里修复它需要一个 hackish 解决方案或自定义 UI 组件来修复 List 组件中看似错误的问题。但是,如果您在更改数据提供者而不是尝试捕获事件时处理逻辑,它似乎可以工作:

public function setDataProvider(data:IList):void {
    var previous:Object = theSparkList.selectedItem;
    theSparkList.dataProvider = data;
    var index:int = theSparkList.dataProvider.getItemIndex(previous);
    if (index > -1) {
        theSparkList.selectedIndex = index;
    }
}

这可能仍然需要一些重构,并且它可能不适用于您的架构 - 您可能需要提供更多详细信息。捕获事件是唯一的选择吗?

于 2012-05-18T14:58:11.057 回答
0
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
               xmlns:s="library://ns.adobe.com/flex/spark"
               xmlns:mx="library://ns.adobe.com/flex/mx"
               creationComplete="_creationCompleteHandler()">
    <s:layout>
        <s:HorizontalLayout />
    </s:layout>
    <fx:Declarations>
        <s:ArrayList id="d1">
            <fx:Object label="Obj1" />
            <fx:Object label="Obj2" />
            <fx:Object label="Obj3" />
            <fx:Object label="Obj4" />
            <fx:Object label="Obj5" />
            <fx:Object label="Obj6" />
            <fx:Object label="Obj7" />
            <fx:Object label="Obj8" />
            <fx:Object label="Obj9" />
            <fx:Object label="Obj10" />
            <fx:Object label="Obj11" />
            <fx:Object label="Obj12" />
            <fx:Object label="Obj13" />
            <fx:Object label="Obj14" />
        </s:ArrayList>

        <s:ArrayList id="d2">
            <fx:Object label="AA1" />
            <fx:Object label="AA2" />
            <fx:Object label="AA3" />
            <fx:Object label="AA4" />
            <fx:Object label="AA5" />
            <fx:Object label="AA6" />
            <fx:Object label="AA7" />
            <fx:Object label="AA8" />
            <fx:Object label="AA9" />
        </s:ArrayList>
    </fx:Declarations>

    <fx:Script>
        <![CDATA[
            import mx.collections.IList;
            import mx.events.PropertyChangeEvent;
            import spark.events.IndexChangeEvent;

            [Bindable]
            public var listDataProvider:IList;

            private var _lastSelectedItemIndex:int = -1;

            private function _creationCompleteHandler():void
            {
                list.addEventListener(IndexChangeEvent.CHANGE, _list_changeHandler);

                addEventListener(PropertyChangeEvent.PROPERTY_CHANGE, _propertyChangeHandler);
                listDataProvider = d1;
            }

            private function changeButt_clickHandler():void
            {
                listDataProvider = d2;
            }

            private function _propertyChangeHandler(event:PropertyChangeEvent):void
            {
                list.selectedIndex = _lastSelectedItemIndex;
            }

            private function _list_changeHandler(event:IndexChangeEvent):void
            {
                _lastSelectedItemIndex = list.selectedIndex;
            }
        ]]>
    </fx:Script>

    <s:List id="list"
            dataProvider="{listDataProvider}"
            height="200" />
    <s:Button label="changeButt"
              click="changeButt_clickHandler()" />
</s:Application>
于 2012-05-18T14:00:34.793 回答
0

也许在更改 dataProvider 时,重新实例化列表控件...... list = new List();,或者类似的东西来清除该控件的设置。

于 2012-05-18T13:23:33.450 回答