前言
duilib的combo box 单击时会弹出下拉框可供选择,但是duilib的combo box本身没有提供文字输入功能,因此,为了实现combo box对输入的文字进行模糊查询,并将查询结果的优先级显示在下拉框内就需要通过添加edit控件的方法来曲线实现
由于我们需要在文本输入过程中实时监测输入的文本是否变化,因此这里我们需要用到edit控件的textchanged消息
添加控件
1:稍微使用duilib的人应该明白duilib的界面可以用读取XML实现(包括控件的名字,颜色,属性设置等),因此添加edit控件可以直接在XML中combo box 的语句下添加如下语句
<Combo name="Comb_operate" float="true" pos="170,110,0,0" width="180" height="24" itemtextpadding="5,0,0,0" itemtextcolor="#FF000000" itemselectedtextcolor="#FF000000" itemselectedbkcolor="#FFC1E3FF" itemhottextcolor="#FF000000" itemhotbkcolor="#FFE9F5FF" itemdisabledtextcolor="#FFCCCCCC" itemdisabledbkcolor="#FFFFFFFF" normalimage="file='Combo_nor.bmp' corner='2,2,24,2'" hotimage="file='Combo_over.bmp' corner='2,2,24,2'" pushedimage="file='Combo_over.bmp' corner='2,2,24,2'" dropboxsize="0,150" />
<Edit name="Edit_Operat" float="true" pos="170,110,0,0" width="160" height="24" bkcolor="#FFFFFFFF" bordercolor="#004EA0D1" textpadding="4,3,4,3" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" />
需要注意的是我们添加的edit控件需要完全覆盖combo box控件除下拉三角图标的其他部分
2:使用XML界面编辑器DuiDesigner.exe
该编辑器如何使用本人就不废话了
效果图如下
上面蓝色的区域就是添加的edit控件,下面的红色部分就是combo box没有被覆盖的部分
注意,DuiDesigner.exe存在诸多bug,每次添加完控件后记得保存
用此方法添加edit时需要修改name属性,我这里的名字是Edit_Operat
将combo box的子项显示到edit上
我们现在已经添加了edit控件,现在要将combo box下拉框中被选择的子项显示在edit上
找到你的void XXX::Notify(TNotifyUI& msg) //添加消息处理函数
我们需要找打的消息类型是itemselect
else if (msg.sType == _T("itemselect")) //combo box控件选择子项__ljl
{
if (msg.pSender->GetName() == _T("Comb_operate")) //将协同操作人combo项显示在协同操作人edit上__ljl
{
m_editoperate->SetText(msg.pSender->GetText());
}
}
实现模糊查询功能
1·找到消息响应
找到你的void XXX::Notify(TNotifyUI& msg) //添加消息处理函数
我们要添加的类型是Textchanged
else if (msg.sType == _T("textchanged")) //内容改变__ljl
{
if (msg.pSender->GetName() == _T("Edit_Operat")) //测试编辑框内容改变__ljl.19/2/18
{
FuzzyQuery(m_pComOprat,msg.pSender->GetText()/*获取edit控件内容*/);
if(0 == iEditEmptyFlag) //初始化combo box下拉框内容
{
InitOperatList();
}
}
}
我代码中的m_pComOprat是combo box指针
CComboUI* m_pComOprat;
FuzzyQuery函数如下
/**************************************************************/
/*
找到edit文本内容改变触发事件__ljl.2019/2/18
*/
/**************************************************************/
void FuzzyQuery(CComboUI* pCombo,CStdString strGoal) //模糊查询
{
OutputDebugString("进入模糊查询__ljl");
if (NULL == strGoal.GetData()) //编辑框中没有内容
{
iEditEmptyFlag = 0; //标志位为0
pCombo->RemoveAll(); //清空combo box 下拉框选项
}
else
{
iEditEmptyFlag = 1; //标志位为1,内容存在
//拷贝combo box下拉框的内容
std::vector<string> LvNamesOK;
std::vector<string> LvNamesUOK;
for(int i = 0; i < pCombo->GetCount(); i++) //找出combo弹窗下有几个项
{
const char * cstr = NULL;
cstr = strstr(pCombo->GetItemAt(i)->GetText().GetData(),strGoal.GetData()/*GetData()的作用是将CStdString转const char*/);
if(NULL != cstr) //将符合的子项保存在LvNamesOK中
{
LvNamesOK.push_back(pCombo->GetItemAt(i)->GetText().GetData());
}
else //将不符合的子项保存在LvNamesUOK中
{
LvNamesUOK.push_back(pCombo->GetItemAt(i)->GetText().GetData());
}
}
//将LvNamesUOK追加到LvNamesOK后
for (vector<string>::iterator it = LvNamesUOK.begin();it != LvNamesUOK.end();it++)
{
LvNamesOK.push_back((*it));
}
pCombo->RemoveAll(); //清空combo box 下拉框选项
//给combo box下拉框重新赋值
std::vector<string>::iterator it;
for (it = LvNamesOK.begin(); it != LvNamesOK.end(); it++)
{
CListLabelElementUI* pElement = new CListLabelElementUI;
if (!pElement)
{
OutputDebugString("创建CListLabelElementUI列表失败");
}
pElement->SetText((*it).c_str());
if (!pCombo->Add(pElement))
{
OutputDebugString("combo box下拉框添加子项失败");
}
}
//pCombo->SelectItem(0);
}
}
由于该操作是嵌入于项目,因此不可能展示全部代码
但这里讲出思路:
获取edit控件内容之后与combo box下拉框进行一一对比,将符合条件的子项保存至容器OK,将不符合的子项保存至UOK然后清空combo box原有的下拉框,重新给下拉框赋值
InitOperatList()代码如下
bool CAuthorDlg::InitOperatList() //协同操作人控件__ljl
{
if (m_vNames.empty())
{
return false;
}
std::vector<string>::iterator it;
for (it = m_vNames.begin(); it != m_vNames.end(); it++)
{
CListLabelElementUI* pElement = new CListLabelElementUI;
if (!pElement)
{
return false;
}
// pElement->SetName(_T("Operater_List"));
pElement->SetText((*it).c_str());
if (!m_pComOprat->Add(pElement))
{
return false;
}
}
m_pComOprat->SelectItem(0);
return true;
}
combo box的下拉框实际上是一个窗体,弹出窗体的过程为combo box的单击响应事件,该窗体又用CListLabelElementUI类型链表存放子项
combo box的单击事件内部实际调用m_pComOprat->Activate();函数