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