我正在使用<mx:ComboBox />并且我想根据通过键盘输入的字符串选择匹配的项目。目前,<mx:ComboBox />仅根据第一个字符选择第一个匹配项。我希望自定义此功能。我找不到进行匹配的 KeyboardEvent 侦听器,以便我可以覆盖它。
2 回答
1
ComboBox要自己执行此操作,您应该从和ListBase类中查看以下代码片段。ListBase是ComboBox组件用于其下拉列表的内容。
似乎将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 回答