拦截值提交事件后,列表中的选择突出显示不会消失

时间:2012-05-18 12:50:34

标签: actionscript-3 flash flex

我正在使用spark列表,并希望在更改作为数据提供者的列表内容后维护选择。如果设置新的数据提供程序,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中的更改注册为可撤消操作,因为只有用户交互才能撤消。

任何想法?

3 个答案:

答案 0 :(得分: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;
    }
}

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

答案 1 :(得分:0)

也许在更改dataProvider时,重新实例化列表控件...... list = new List();或沿着这些行清除该控件的设置。

答案 2 :(得分: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>