我正在使用<mx:ComboBox />
,我想根据通过键盘输入的字符串选择匹配的项目。目前,<mx:ComboBox />
仅根据第一个字符选择第一个匹配项。我希望自定义此功能。我无法找到执行匹配的KeyboardEvent侦听器,以便我可以覆盖它。
答案 0 :(得分:1)
要自己执行此操作,您应该查看以下ComboBox
和ListBase
类中的以下代码。 ListBase
是ComboBox
组件用于其下拉列表的内容。
ComboBox
似乎是将键盘输入推迟到下拉列表。然后,它会从下拉列表中侦听事件,以了解选择何时发生更改(作为键盘或鼠标输入的结果)。
Flex组件通常会覆盖名为keyDownHandler()
的方法,以便在有焦点时处理键盘输入。从那里开始,我们遇到ComboBox line 2231:
// Redispatch the event to the dropdown
// and let its keyDownHandler() handle it.
dropdown.dispatchEvent(event.clone());
event.stopPropagation();
现在,下拉列表中的keyDownHandler()
将被执行。该方法有一个巨大的switch
语句,其中default
case语句on line 9197 of ListBase如下所示:
default:
{
if (findKey(event.charCode))
event.stopPropagation();
}
这是下拉列表根据键盘输入决定选择的内容(当输入不是箭头键或向上翻页时等)。受保护的findKey()
方法只需调用公共findString()
方法即可完成此项工作。
所以要自己覆盖这种行为:
ListBase
类并使用您的自定义逻辑覆盖findKey()
或findString()
方法ComboBox
类并覆盖createChildren()
方法,以便您可以实例化自定义ListBase
类而不是默认类。答案 1 :(得分:1)
这是我为了使其发挥作用而使用的课程。 searchStr
是用户输入的字符串,需要匹配。如果没有dataprovider项与searchStr
匹配,则重写的侦听器将回退到默认行为。我使用Timer
在2秒后刷新输入的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();
}
}