在Flex 4列表中处理鼠标单击以查找所选项目(因为itemClick已消失)

Ale*_*ber 3 apache-flex list click flex4 flex4.5

我为我的问题准备了一个简化的测试用例.如果将下面的2个文件放入项目中,它将立即在Flash Builder中运行.

我正在尝试在弹出窗口中显示字符串列表和确认复选框:

截图

在实际应用程序中,我使用列表中选择的字符串调度自定义事件,但在下面的测试代码中我只调用trace(str);

我的问题:如果我使用单击事件,然后在窗口关闭,即使我点击滚动条(对!STR检查下面没有帮助,当已经在以前的使用而选择的项目).如果我使用更改事件,那么当我单击与上次相同的项目时,窗口不会关闭.并且itemClick事件似乎不再存在于spark.components.List中.

有关如何处理这个可能经常出现问题的任何建议吗?

编写自定义项呈示器并为每个项目设置单击事件处理程序对于这种情况似乎有点过分,因为我在列表中有字符串.

Test.mxml :(请点击myBtn几次 - 查看我点击更改的问题)

<?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" 
    minWidth="400" minHeight="300">

    <fx:Script>
        <![CDATA[
            import mx.managers.PopUpManager;

            private var _popup:Popup = new Popup();

            private function showPopup(event:MouseEvent):void {
                PopUpManager.addPopUp(_popup, this, true);
                PopUpManager.centerPopUp(_popup);
            }
        ]]>
    </fx:Script>

    <s:Button id="myBtn" right="5" bottom="5" 
        label="Open window" click="showPopup(event)" />

</s:Application>
Run Code Online (Sandbox Code Playgroud)

Popup.mxml:

<?xml version="1.0" encoding="utf-8"?>
<s:TitleWindow 
    xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:s="library://ns.adobe.com/flex/spark" 
    xmlns:mx="library://ns.adobe.com/flex/mx"
    width="240" height="240"
    creationComplete="init(event)"
    close="close()">    

    <fx:Script>
        <![CDATA[
            import mx.collections.ArrayList;
            import mx.controls.Alert;
            import mx.events.FlexEvent;
            import mx.events.CloseEvent;
            import mx.events.ItemClickEvent;
            import mx.managers.PopUpManager;

            private var myData:ArrayList = new ArrayList();

            private function init(event:FlexEvent):void {
                // XXX in the real app data is updated from server
                myData.removeAll();
                for (var i:uint = 1; i <= 10; i++)
                    myData.addItem('Item #' + i);
            }

            public function close(event:TimerEvent=null):void {
                PopUpManager.removePopUp(this);
            }

            private function handleClick(event:MouseEvent):void {
                var str:String = myList.selectedItem as String;
                if (!str)
                    return;

                if (myBox.selected) {
                    Alert.show(
                        'Select ' + str + '?', 
                        null, 
                        mx.controls.Alert.YES | mx.controls.Alert.NO,
                        null,
                        handleConfirm,
                        null,
                        mx.controls.Alert.NO
                    );
                } else {
                    sendEvent();
                }
            }

            private function handleConfirm(event:CloseEvent):void {
                if (event.detail == mx.controls.Alert.YES)
                    sendEvent();
            }

            private function sendEvent():void {
                close();
                // XXX in the real app dispatchEvent() is called
                trace('selected: ' + (myList.selectedItem as String));
            }
        ]]>
    </fx:Script>

    <s:VGroup paddingLeft="20" paddingTop="20" 
            paddingRight="20" paddingBottom="20" gap="20" 
            width="100%" height="100%">
        <s:List id="myList" dataProvider="{myData}" 
            click="handleClick(event)"
            width="100%" height="100%" fontSize="24" />
        <s:CheckBox id="myBox" label="Confirm" />
    </s:VGroup>
</s:TitleWindow>
Run Code Online (Sandbox Code Playgroud)

我也想知道,为什么我会收到上面的警告:

Data binding will not be able to detect assignments to "myData".
Run Code Online (Sandbox Code Playgroud)

RIA*_*tar 5

Spark List调度' IndexChangeEvent .CHANGE'.您可以侦听此事件,以了解列表中的选择何时发生更改.

    <s:List id="myList" dataProvider="{myData}" 
            change="handleIndexChange()"
            width="100%" height="100%" fontSize="24" />
Run Code Online (Sandbox Code Playgroud)

只有当所选索引实际更改时才会调度该事件,这意味着当您再次打开窗口时,可能仍会选择一个项目,当您单击该项目时,不会触发任何CHANGE事件.要解决此问题,只需在关闭窗口之前取消选择选择:

        public function close():void {
            myList.selectedIndex = -1;
            PopUpManager.removePopUp(this);
        }
Run Code Online (Sandbox Code Playgroud)

还要确保关闭窗口之前使用所选项目调度事件(并取消选中).

至于你关于绑定警告的问题:你得到了那条消息,因为你没有将'myData'标记为可绑定.要解决这个问题,只需使用[Bindable]标签:

[Bindable]
private var myData:ArrayList = new ArrayList();
Run Code Online (Sandbox Code Playgroud)

如果您不需要它,则完全跳过绑定,只需将Dataaprovider分配给ActionScript中的列表:

myList.dataProvider = myData;
Run Code Online (Sandbox Code Playgroud)