duilib库combo box提供输入字符模糊查询

前言

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=&apos;Combo_nor.bmp&apos; corner=&apos;2,2,24,2&apos;" hotimage="file=&apos;Combo_over.bmp&apos; corner=&apos;2,2,24,2&apos;" pushedimage="file=&apos;Combo_over.bmp&apos; corner=&apos;2,2,24,2&apos;" 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();函数

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值