0

我正在使用<mx:ComboBox />并且我想根据通过键盘输入的字符串选择匹配的项目。目前,<mx:ComboBox />仅根据第一个字符选择第一个匹配项。我希望自定义此功能。我找不到进行匹配的 KeyboardEvent 侦听器,以便我可以覆盖它。

4

2 回答 2

1

ComboBox要自己执行此操作,您应该从和ListBase类中查看以下代码片段。ListBaseComboBox组件用于其下拉列表的内容。

似乎将ComboBox键盘输入推迟到下拉列表。然后它从下拉列表中侦听事件以了解选择何时更改(作为键盘或鼠标输入的结果)。

Flex 组件通常会覆盖一个在获得焦点时调用keyDownHandler()以处理键盘输入的方法。从那里开始,我们遇到了ComboBox 第 2231 行

// Redispatch the event to the dropdown
// and let its keyDownHandler() handle it.

dropdown.dispatchEvent(event.clone());
event.stopPropagation();

所以现在keyDownHandler()下拉列表中的将被执行。该方法有一个巨大的switch语句,其中ListBase 的第 9197 行default的case 语句如下所示:

default:
{
    if (findKey(event.charCode))
        event.stopPropagation();
}

这是下拉列表根据键盘输入决定选择什么的地方(当输入不是箭头键或向上翻页等时)。受保护的findKey()方法只是调用公共findString()方法来完成这项工作。

因此,要自己覆盖此行为:

  • 扩展类并使用您的自定义逻辑ListBase覆盖findKey()or方法findString()
  • 扩展ComboBox类并覆盖该createChildren()方法,以便您可以实例化自定义ListBase类而不是默认类。
于 2013-10-17T05:24:16.737 回答
1

这是我用来使它工作的类。searchStr是用户输入的需要匹配的字符串。如果没有 dataprovider 项与 匹配,则被searchStr覆盖的侦听器回退到默认行为。我用来在 2 秒后Timer刷新输入的内容。searchStr可能的缺点是它假设数据提供者是String值的集合。但是您可以根据需要进行相应的修改。

public class CustomComboBox extends ComboBox
    {
        private var searchStr:String="";
        private var ticker:Timer;
        public function CustomComboBox()
        {
            super();
            ticker = new Timer(2000);
            ticker.addEventListener(TimerEvent.TIMER, resetSearchString);
        }

        override protected function keyDownHandler(event:KeyboardEvent):void
        {
            super.keyDownHandler(event);

            // code to search items in the list based on user input.
            // Earlier, the default behavior shows the matched items in the dropdown,  based on first character only.
            // user input is invisible to user.
            if((event.charCode>=0x20 && event.charCode<=0x7E) || event.charCode==8)             //Range of printable characters is 0x20[space] to 0x7E[~] in ASCII. 8 is ASCII code of [backspace].
            {
                ticker.reset();
                ticker.start();

                if(event.charCode==8)
                {
                    if(searchStr=="")
                        return;
                    searchStr = searchStr.substr(0, searchStr.length-1);
                }
                else
                {
                    searchStr += String.fromCharCode(event.charCode);
                    searchStr = searchStr.toLowerCase();
                }
                for each(var str:String in dataProvider)
                {
                    if(str.toLowerCase().indexOf(searchStr, 0)>-1)
                    {
                        this.selectedItem = dropdown.selectedItem = str;
                        dropdown.scrollToIndex(dropdown.selectedIndex);

                        break;
                    }
                }
            }
        }


        /**
         * reset the search string and reset the timer.
         **/ 
        private function resetSearchString(evt:TimerEvent):void
        {
            searchStr = "";
            ticker.reset();
        }
    }
于 2013-10-18T04:28:27.520 回答