1

Spark Listを使用していて、データプロバイダーであるリストのコンテンツを変更した後も選択を維持したいと考えています。新しいデータプロバイダーを設定すると、リストはそのselectedIndexを-1に戻します。この問題は、リストが自分自身を-1に戻したいときに発生するvalueCommitイベントをインターセプトし、以前に選択したアイテムを設定することで解決しました(新しいデータプロバイダーにまだ含まれている場合)。これは今のところ機能しますが、奇妙な動作をしています。

  • 最初に、以前に選択されたアイテムが引き続き選択され、意図したとおりに強調表示されます
  • 別のアイテムが選択された場合、強調表示は最初のアイテムにとどまります。別のアイテムを選択する頻度は関係ありません。最初のアイテムは強調表示されますが、選択されません。新しく選択されたアイテムが実際に選択され、強調表示されます。
  • 最初の項目を再度選択すると、リストは再び正常に動作します。最初のアイテムを一度再選択した後で別のアイテムを選択すると、強調表示が消えます。

リストは、次のように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は、元に/やり直しを処理するクラスです。無視関数は、ユーザーの操作のみを元に戻すことができるため、undoManagerがdataProviderに変更を元に戻すことができるアクションとして登録しないように注意します。

何か案は?

4

3 に答える 3

1

変更イベントをキャプチャすると、説明した結果が得られました。それを修正するには、リスト コンポーネントのバグのように見えるものを修正するために、ハック ソリューションまたはカスタム UI コンポーネントが必要です。ただし、イベントをキャプチャしようとするのではなく、データ プロバイダーを変更するときにロジックを処理するとうまくいくようです。

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 に答える