NSComboBox输入字符时自动打开下拉菜单并匹配
2012-12-23 11:39
316 查看
NSComboBox,此功能实现的效果图如下图所示:
1. 首先调用NSComboBox的父类NSTextField的delegate方法,实现实时输入监测。其中比较关键的方法是-(void)controlTextDidChange:(NSNotification*)notification,这个方法可以实现输入内容的实时监测。
-(void)controlTextDidChange:(NSNotification*)notification
{
id object = [notification object];
[object setComplete:YES];//这个函数可以实现自动匹配功能
}
2. 可以看到,在NSComboBox控件的右边有一个标有下三角的按钮,这个按钮在鼠标点击后才弹出下拉菜单来,但是我们在输入的时候没有实现鼠标事件,所以下来菜单无法弹出,因此需要模拟鼠标事件-(void)mouseDown:(NSEvent*)theEvent,但是这个按钮是NSComboBoxCell中的私有变量,所以我们重新创建一个类,这个类继承NSComboBoxCell,这样我们就可以应用它的私有变量了。
继承NSComboBox类:
@interface ComboBoxCell : NSComboBoxCell
{
}
- (void)popUpList;
- (void)closePopUpWindow;
- (BOOL)isPopUpWindowVisible;
@end
@implementation ComboBoxCell
- (void)popUpList
{
if ([self isPopUpWindowVisible])
{
return;
}
else
{
[_buttonCell performClick:nil];//模拟鼠标事件
}
}
- (void)closePopUpWindow
{
if ([self isPopUpWindowVisible])
{
[_popUp close];
}
}
- (BOOL)isPopUpWindowVisible
{
return [_popUp isVisible];
}
@end
3. 实现NSComboBox类的Datasource方法:
- (NSInteger)numberOfItemsInComboBox:(NSComboBox *)aComboBox;
- (id)comboBox:(NSComboBox *)aComboBox objectValueForItemAtIndex:(NSInteger)index;
- (NSUInteger)comboBox:(NSComboBox *)aComboBox indexOfItemWithStringValue:(NSString *)string;
这是Datasource方法,我们需要重写此方法。下面是三个方法的实现,方法中的结构体可以根据用户的需要自定义。
- (NSInteger)numberOfItemsInComboBox:(NSComboBox *)aComboBox
{
NSInteger row = 0;
if (currentBoxIndex_ == -1)
{
return row;
}
DBBoxManager *currentBox = [[DBManager defaultDBManager] boxAtIndex:currentBoxIndex_];
if ([vendorControl_ isEqual:aComboBox])
{
row = [currentBox userDefineVenderInfos].count;
}
else if ([categoryControl_ isEqual:aComboBox])
{
row = [currentBox userDefineCategoryInfos].count;
}
else if ([paymentControl_ isEqual:aComboBox])
{
row = [currentBox userDefinePaymentInfos].count;
}
else if ([purposeControl_ isEqual:aComboBox])
{
row = [currentBox userDefinePurposeInfos].count;
}
else if ([categorySelectBtn_ isEqual:aComboBox])
{
row = [currentBox userDefineCategoryInfos].count;
}
else if([vendorSelectBtn_ isEqual:aComboBox])
{
row = [currentBox userDefineVenderInfos].count;
}
row = row + 1;
return row;
}
- (id)comboBox:(NSComboBox *)aComboBox objectValueForItemAtIndex:(NSInteger)index
{
NSString *content = nil;
if (currentBoxIndex_ == -1)
{
return content;
}
NSMutableArray *array = nil;
DBBoxManager *currentBox = [[DBManager defaultDBManager] boxAtIndex:currentBoxIndex_];
if ([vendorControl_ isEqual:aComboBox])
{
array = [currentBox userDefineVenderInfos];
}
else if ([categoryControl_ isEqual:aComboBox])
{
array = [currentBox userDefineCategoryInfos];
}
else if ([paymentControl_ isEqual:aComboBox])
{
array = [currentBox userDefinePaymentInfos];
}
else if ([purposeControl_ isEqual:aComboBox])
{
array = [currentBox userDefinePurposeInfos];
}
else if ([categorySelectBtn_ isEqual:aComboBox])
{
array = [currentBox userDefineCategoryInfos];
}
else if ([vendorSelectBtn_ isEqual:aComboBox])
{
array = [currentBox userDefineVenderInfos];
}
if (index == 0)
{
content = @"";
}
else
{
NSDictionary *dic = [array objectAtIndex:index - 1];
content = (NSString *)[dicobjectForKey:kUserDefinedBoxValue];
}
return content;
}
- (NSUInteger)comboBox:(NSComboBox *)aComboBox indexOfItemWithStringValue:(NSString *)string
{
DBBoxManager *currentBox = [[DBManager defaultDBManager] boxAtIndex:currentBoxIndex_];
NSMutableArray *comboxList = nil;
if ([aComboBox isEqual:vendorControl_])
{
comboxList = [currentBox userDefineVenderInfos];
}
else if([aComboBox isEqual:categoryControl_])
{
comboxList = [currentBox userDefineCategoryInfos];
}
else if([aComboBox isEqual:paymentControl_])
{
comboxList = [currentBox userDefinePaymentInfos];
}
else if([aComboBox isEqual:purposeControl_])
{
comboxList = [currentBox userDefinePurposeInfos];
}
NSMutableArray *newList = [[[NSMutableArray alloc] initWithCapacity:0] autorelease];
[newList addObject:@""];
for (int i = 0; i < [comboxList count]; i++)
{
NSString *name = [[comboxList objectAtIndex:i] objectForKey:kUserDefinedBoxValue];
[newList addObject:name];
}
return [newList indexOfObject:string];
}
做到这里,这个功能就基本实现了,本文中的代码来自正在开发的工程,读者只需替换响应的结构体,即可实现功能。
1. 首先调用NSComboBox的父类NSTextField的delegate方法,实现实时输入监测。其中比较关键的方法是-(void)controlTextDidChange:(NSNotification*)notification,这个方法可以实现输入内容的实时监测。
-(void)controlTextDidChange:(NSNotification*)notification
{
id object = [notification object];
[object setComplete:YES];//这个函数可以实现自动匹配功能
}
2. 可以看到,在NSComboBox控件的右边有一个标有下三角的按钮,这个按钮在鼠标点击后才弹出下拉菜单来,但是我们在输入的时候没有实现鼠标事件,所以下来菜单无法弹出,因此需要模拟鼠标事件-(void)mouseDown:(NSEvent*)theEvent,但是这个按钮是NSComboBoxCell中的私有变量,所以我们重新创建一个类,这个类继承NSComboBoxCell,这样我们就可以应用它的私有变量了。
继承NSComboBox类:
@interface ComboBoxCell : NSComboBoxCell
{
}
- (void)popUpList;
- (void)closePopUpWindow;
- (BOOL)isPopUpWindowVisible;
@end
@implementation ComboBoxCell
- (void)popUpList
{
if ([self isPopUpWindowVisible])
{
return;
}
else
{
[_buttonCell performClick:nil];//模拟鼠标事件
}
}
- (void)closePopUpWindow
{
if ([self isPopUpWindowVisible])
{
[_popUp close];
}
}
- (BOOL)isPopUpWindowVisible
{
return [_popUp isVisible];
}
@end
3. 实现NSComboBox类的Datasource方法:
- (NSInteger)numberOfItemsInComboBox:(NSComboBox *)aComboBox;
- (id)comboBox:(NSComboBox *)aComboBox objectValueForItemAtIndex:(NSInteger)index;
- (NSUInteger)comboBox:(NSComboBox *)aComboBox indexOfItemWithStringValue:(NSString *)string;
这是Datasource方法,我们需要重写此方法。下面是三个方法的实现,方法中的结构体可以根据用户的需要自定义。
- (NSInteger)numberOfItemsInComboBox:(NSComboBox *)aComboBox
{
NSInteger row = 0;
if (currentBoxIndex_ == -1)
{
return row;
}
DBBoxManager *currentBox = [[DBManager defaultDBManager] boxAtIndex:currentBoxIndex_];
if ([vendorControl_ isEqual:aComboBox])
{
row = [currentBox userDefineVenderInfos].count;
}
else if ([categoryControl_ isEqual:aComboBox])
{
row = [currentBox userDefineCategoryInfos].count;
}
else if ([paymentControl_ isEqual:aComboBox])
{
row = [currentBox userDefinePaymentInfos].count;
}
else if ([purposeControl_ isEqual:aComboBox])
{
row = [currentBox userDefinePurposeInfos].count;
}
else if ([categorySelectBtn_ isEqual:aComboBox])
{
row = [currentBox userDefineCategoryInfos].count;
}
else if([vendorSelectBtn_ isEqual:aComboBox])
{
row = [currentBox userDefineVenderInfos].count;
}
row = row + 1;
return row;
}
- (id)comboBox:(NSComboBox *)aComboBox objectValueForItemAtIndex:(NSInteger)index
{
NSString *content = nil;
if (currentBoxIndex_ == -1)
{
return content;
}
NSMutableArray *array = nil;
DBBoxManager *currentBox = [[DBManager defaultDBManager] boxAtIndex:currentBoxIndex_];
if ([vendorControl_ isEqual:aComboBox])
{
array = [currentBox userDefineVenderInfos];
}
else if ([categoryControl_ isEqual:aComboBox])
{
array = [currentBox userDefineCategoryInfos];
}
else if ([paymentControl_ isEqual:aComboBox])
{
array = [currentBox userDefinePaymentInfos];
}
else if ([purposeControl_ isEqual:aComboBox])
{
array = [currentBox userDefinePurposeInfos];
}
else if ([categorySelectBtn_ isEqual:aComboBox])
{
array = [currentBox userDefineCategoryInfos];
}
else if ([vendorSelectBtn_ isEqual:aComboBox])
{
array = [currentBox userDefineVenderInfos];
}
if (index == 0)
{
content = @"";
}
else
{
NSDictionary *dic = [array objectAtIndex:index - 1];
content = (NSString *)[dicobjectForKey:kUserDefinedBoxValue];
}
return content;
}
- (NSUInteger)comboBox:(NSComboBox *)aComboBox indexOfItemWithStringValue:(NSString *)string
{
DBBoxManager *currentBox = [[DBManager defaultDBManager] boxAtIndex:currentBoxIndex_];
NSMutableArray *comboxList = nil;
if ([aComboBox isEqual:vendorControl_])
{
comboxList = [currentBox userDefineVenderInfos];
}
else if([aComboBox isEqual:categoryControl_])
{
comboxList = [currentBox userDefineCategoryInfos];
}
else if([aComboBox isEqual:paymentControl_])
{
comboxList = [currentBox userDefinePaymentInfos];
}
else if([aComboBox isEqual:purposeControl_])
{
comboxList = [currentBox userDefinePurposeInfos];
}
NSMutableArray *newList = [[[NSMutableArray alloc] initWithCapacity:0] autorelease];
[newList addObject:@""];
for (int i = 0; i < [comboxList count]; i++)
{
NSString *name = [[comboxList objectAtIndex:i] objectForKey:kUserDefinedBoxValue];
[newList addObject:name];
}
return [newList indexOfObject:string];
}
做到这里,这个功能就基本实现了,本文中的代码来自正在开发的工程,读者只需替换响应的结构体,即可实现功能。
相关文章推荐
- 实用文本框输入字符后下拉菜单内容自动匹配效果
- AutoCompleteTextView控件---输入字符自动匹配
- 利用js进行输入框自动匹配字符
- 利用js 进行输入框自动匹配字符的小例子
- 利用js 进行输入框自动匹配字符的小例子
- WPF DevExpress ComboBoxEdit 实现键值绑定,输入字符自动匹配
- 请教关于下拉菜单可输入文本自动匹配的问题
- 使用AutoCompleteTextView实现自动匹配输入的内容
- Android之实现动态自动匹配输入
- php+ajax实时输入自动搜索匹配的方法
- jQuery验证,匹配输入非中文的正则表达式,输入内容可以是包括空格等特殊字符的任何字符。
- JQuery EasyUI+Struts2自动匹配输入下拉框(combobox)
- 考试系统——可输入并自动匹配的下拉框(二)——JQuery Easy UI框架
- 在程序开始运行时,系统自动打开3个标准文件:标准输入、标准输出、标准出错输出
- [原]考试系统——可输入并自动匹配的下拉框(三)——Html,Web控件级联
- linux新建用户后shell无法自动补全命令,Backspace无法删除字符,无法翻看输入纪录
- JS判断字符输入个数(数字英文长度记为1,中文记为2,超过长度自动截取)
- Android控件之自动匹配输入内容AutoCompleteTextView
- 字符串查找匹配位置-在输入的字符串中查找特定字符,查到返回位置和个数
- MFC COMBOBOX 短代码 实现的自动匹配输入 自动完成 但有小缺陷