duilib List 动态添加

一、为什么需要动态添加?

由于我不知道我的List头的项目到底是哪些,我的List中有多少行数据需要添加,动态添加就比较合适,方便。

二、实现

1、Xml配置

 

	 <HorizontalLayout name="ListContainer" height="450">
	<!-- <List name="ShowList" float="true" pos="30,0,0,0" width="740" height="450" sepheight="1" itemalign="center" itembkcolor="#FFE2DDDF" itemaltbk="true" >
         (List动态添加位置)
	 </List> -->
	 </HorizontalLayout>

2、C++代码

 

 

CHorizontalLayoutUI * pHor = static_cast<CHorizontalLayoutUI*>(m_PaintManager.FindControl(_T("ListContainer")));

	CListUI * pList = new CListUI;
	pList->ApplyAttributeList(_T("name=\"ShowList\" float=\"true\" pos=\"30,0,0,0\" width=\"740\" height=\"450\" sepheight=\"1\" itemalign=\"center\" itembkcolor=\"#FFE2DDDF\" itemaltbk=\"true\""));

	pHor->Add(pList);
	//CListUI * pList = static_cast<CListUI*>(m_PaintManager.FindControl(_T("ShowList")));
	pList->RemoveAll();

	CListHeaderUI * pHeader = new CListHeaderUI;
	pList->Add(pHeader);

	//CListHeaderUI *pHeader = static_cast<CListHeaderUI*>(m_PaintManager.FindControl(_T("Listheader")));
	CListHeaderItemUI *pListHeaderItemIP = new CListHeaderItemUI;
	pListHeaderItemIP->ApplyAttributeList(_T("text=\"IP\"   width=\"100\"  height=\"30\" sepwidth=\"1\""  ));

	CListHeaderItemUI *pListHeaderItemCmd = new CListHeaderItemUI;
	pListHeaderItemCmd->ApplyAttributeList(_T("text=\"Command\"   width=\"100\"  height=\"30\" sepwidth=\"1\"" ));

	CListHeaderItemUI *pListHeaderItemDb = new CListHeaderItemUI;
	pListHeaderItemDb->ApplyAttributeList(_T("text=\"DbName\"   width=\"100\"  height=\"30\" sepwidth=\"1\"" ));

	CListHeaderItemUI *pListHeaderItemUser = new CListHeaderItemUI;
	pListHeaderItemUser->ApplyAttributeList(_T("text=\"User\"   width=\"100\"  height=\"30\" sepwidth=\"1\"" ));

	CListHeaderItemUI *pListHeaderItemInfo = new CListHeaderItemUI;
	pListHeaderItemInfo->ApplyAttributeList(_T("text=\"Info\" itemendellipsis=\"true\"  width=\"100\"  height=\"30\" sepwidth=\"1\"" ));

	CListHeaderItemUI *pListHeaderItemTime = new CListHeaderItemUI;
	pListHeaderItemTime->ApplyAttributeList(_T("text=\"Time\"   width=\"100\"  height=\"30\" sepwidth=\"1\"" ));

	pList->Add(pListHeaderItemIP);
	pList->Add(pListHeaderItemCmd);
	pList->Add(pListHeaderItemDb);
	pList->Add(pListHeaderItemUser);
	pList->Add(pListHeaderItemInfo);
	pList->Add(pListHeaderItemTime);

	//pList->Add(pHeader);
	for(VEC_MYSQLSYSINFO_ITOR it = vecsysinfo.begin(); it != vecsysinfo.end(); it++ )
	{
		CListTextElementUI *pListElement = new CListTextElementUI;
		//pListElement->ApplyAttributeList(_T("textcolor=\"#FF000000\""));
		pList->Add(pListElement);
		pListElement->SetText(0,Utf82T(it->strHost.c_str()).c_str());
		pListElement->SetText(1, Utf82T(it->strCmd.c_str()).c_str());
		pListElement->SetText(2, Utf82T(it->strDb.c_str()).c_str());
		pListElement->SetText(3, Utf82T(it->strUser.c_str()).c_str());
		pListElement->SetText(4, Utf82T(it->strInfo.c_str()).c_str());;
		TString strPort;
		TCHAR tcPort[10];
		 _itow(it->nTime, tcPort, 10);
		pListElement->SetText(5, tcPort);
	}


3、运行效果图

 

所有的都动态添加

xml配置

	 <HorizontalLayout name="ListContainer" height="450">
	   <!--<List name="ShowList" float="true" pos="30,0,0,0" width="740" height="450" sepheight="1" itemalign="center" itembkcolor="#FFE2DDDF" itemaltbk="true" >
		<ListHeader>
		</ListHeader>
	   </List>-->
	 </HorizontalLayout>
        <HorizontalLayout name="ShowExtra">
      
     </HorizontalLayout>

 

C++代码

 

 

VEC_MYSQLSYSINFO vecsysinfo;
	int nNums = m_MySqlOper->ShowConnectNum(vecsysinfo);//从数据库查询数据
	CHorizontalLayoutUI * pHorExtra = static_cast<CHorizontalLayoutUI*>(m_PaintManager.FindControl(_T("ShowExtra")));
	
	CLabelUI * pConNum = new CLabelUI;
	pConNum->ApplyAttributeList(_T("text=\"连接数量:\" float=\"true\" pos=\"300,0,0,0\" width=\"100\" height=\"30\" align=\"right\""));
	TString strText = Format(_T("连接数量:%d"), nNums);
	pConNum->SetText(strText.c_str());

	pHorExtra->Add(pConNum);

	CHorizontalLayoutUI * pHor = static_cast<CHorizontalLayoutUI*>(m_PaintManager.FindControl(_T("ListContainer")));

	CListUI * pList = new CListUI;
	pList->ApplyAttributeList(_T("name=\"ShowList\" childpadding=\"1\" itemlinecolor=\"#FFF4F4F4\" bkcolor=\"#FFC0C0C0\" float=\"true\" pos=\"30,0,0,0\" width=\"740\" height=\"450\" sepheight=\"1\" itemalign=\"center\" itembkcolor=\"#FFE2DDDF\" itemaltbk=\"true\""));

	//CListUI * pList = static_cast<CListUI*>(m_PaintManager.FindControl(_T("ShowList")));
	//pList->RemoveAll();

	CListHeaderUI * pHeader = new CListHeaderUI;
	pHeader->ApplyAttributeList(_T("bkcolor=\"#FF36CA61\""));

	//CListHeaderUI *pHeader = static_cast<CListHeaderUI*>(m_PaintManager.FindControl(_T("Listheader")));
	CListHeaderItemUI *pListHeaderItemIP = new CListHeaderItemUI;
	pListHeaderItemIP->ApplyAttributeList(_T("text=\"IP\"   width=\"100\"  height=\"30\" sepwidth=\"1\""  ));

	CListHeaderItemUI *pListHeaderItemCmd = new CListHeaderItemUI;
	pListHeaderItemCmd->ApplyAttributeList(_T("text=\"Command\"   width=\"100\"  height=\"30\" sepwidth=\"1\"" ));

	CListHeaderItemUI *pListHeaderItemDb = new CListHeaderItemUI;
	pListHeaderItemDb->ApplyAttributeList(_T("text=\"DbName\"   width=\"100\"  height=\"30\" sepwidth=\"1\"" ));

	CListHeaderItemUI *pListHeaderItemUser = new CListHeaderItemUI;
	pListHeaderItemUser->ApplyAttributeList(_T("text=\"User\"   width=\"100\"  height=\"30\" sepwidth=\"1\"" ));

	CListHeaderItemUI *pListHeaderItemInfo = new CListHeaderItemUI;
	pListHeaderItemInfo->ApplyAttributeList(_T("text=\"Info\" itemendellipsis=\"true\"  width=\"100\"  height=\"30\" sepwidth=\"1\"" ));

	CListHeaderItemUI *pListHeaderItemTime = new CListHeaderItemUI;
	pListHeaderItemTime->ApplyAttributeList(_T("text=\"Time\"   width=\"100\"  height=\"30\" sepwidth=\"1\"" ));

// 	pList->Add(pListHeaderItemIP);
// 	pList->Add(pListHeaderItemCmd);
// 	pList->Add(pListHeaderItemDb);
// 	pList->Add(pListHeaderItemUser);
// 	pList->Add(pListHeaderItemInfo);
// 	pList->Add(pListHeaderItemTime);

	//两种方式,上面直接添加到List上面比较稳妥,但是结构没有添加到ListHeader清晰
	pHeader->Add(pListHeaderItemIP);
	pHeader->Add(pListHeaderItemCmd);
	pHeader->Add(pListHeaderItemDb);
	pHeader->Add(pListHeaderItemUser);
	pHeader->Add(pListHeaderItemInfo);
	pHeader->Add(pListHeaderItemTime);
	pList->Add(pHeader);

	//pHeader->Add(pListHeaderItemTime);
	for(VEC_MYSQLSYSINFO_ITOR it = vecsysinfo.begin(); it != vecsysinfo.end(); it++ )
	{
		CListTextElementUI *pListElement = new CListTextElementUI;
		//pListElement->ApplyAttributeList(_T("textcolor=\"#FF000000\""));
		pList->Add(pListElement);
		pListElement->SetText(0,Utf82T(it->strHost.c_str()).c_str());
		pListElement->SetText(1, Utf82T(it->strCmd.c_str()).c_str());
		pListElement->SetText(2, Utf82T(it->strDb.c_str()).c_str());
		pListElement->SetText(3, Utf82T(it->strUser.c_str()).c_str());
		pListElement->SetText(4, Utf82T(it->strInfo.c_str()).c_str());;
		TString strPort;
		TCHAR tcPort[10];
		 _itow(it->nTime, tcPort, 10);
		pListElement->SetText(5, tcPort);
	}
	pHor->Add(pList);

 

 

 

 

 

 

三、有趣的东西(xml配置了代码不识别)

xml配置

 

	 <HorizontalLayout name="ListContainer" height="450">
	   <List name="ShowList" float="true" pos="30,0,0,0" width="740" height="450" sepheight="1" itemalign="center" itembkcolor="#FFE2DDDF" itemaltbk="true" >
		<ListHeader>
		</ListHeader>
	   </List>
	 </HorizontalLayout>

C++代码

 

 

	CListUI * pList = static_cast<CListUI*>(m_PaintManager.FindControl(_T("ShowList")));
	//pList->RemoveAll();

	//CListHeaderUI * pHeader = new CListHeaderUI;
	//pList->Add(pHeader);

	//CListHeaderUI *pHeader = static_cast<CListHeaderUI*>(m_PaintManager.FindControl(_T("Listheader")));
	CListHeaderItemUI *pListHeaderItemIP = new CListHeaderItemUI;
	pListHeaderItemIP->ApplyAttributeList(_T("text=\"IP\"   width=\"100\"  height=\"30\" sepwidth=\"1\""  ));

	CListHeaderItemUI *pListHeaderItemCmd = new CListHeaderItemUI;
	pListHeaderItemCmd->ApplyAttributeList(_T("text=\"Command\"   width=\"100\"  height=\"30\" sepwidth=\"1\"" ));

	CListHeaderItemUI *pListHeaderItemDb = new CListHeaderItemUI;
	pListHeaderItemDb->ApplyAttributeList(_T("text=\"DbName\"   width=\"100\"  height=\"30\" sepwidth=\"1\"" ));

	CListHeaderItemUI *pListHeaderItemUser = new CListHeaderItemUI;
	pListHeaderItemUser->ApplyAttributeList(_T("text=\"User\"   width=\"100\"  height=\"30\" sepwidth=\"1\"" ));

	CListHeaderItemUI *pListHeaderItemInfo = new CListHeaderItemUI;
	pListHeaderItemInfo->ApplyAttributeList(_T("text=\"Info\" itemendellipsis=\"true\"  width=\"100\"  height=\"30\" sepwidth=\"1\"" ));

	CListHeaderItemUI *pListHeaderItemTime = new CListHeaderItemUI;
	pListHeaderItemTime->ApplyAttributeList(_T("text=\"Time\"   width=\"100\"  height=\"30\" sepwidth=\"1\"" ));

	pList->Add(pListHeaderItemIP);
	pList->Add(pListHeaderItemCmd);
	pList->Add(pListHeaderItemDb);
	pList->Add(pListHeaderItemUser);
	pList->Add(pListHeaderItemInfo);
	pList->Add(pListHeaderItemTime);

	//pList->Add(pHeader);
	for(VEC_MYSQLSYSINFO_ITOR it = vecsysinfo.begin(); it != vecsysinfo.end(); it++ )
	{
		CListTextElementUI *pListElement = new CListTextElementUI;
		//pListElement->ApplyAttributeList(_T("textcolor=\"#FF000000\""));
		pList->Add(pListElement);
		pListElement->SetText(0,Utf82T(it->strHost.c_str()).c_str());
		pListElement->SetText(1, Utf82T(it->strCmd.c_str()).c_str());
		pListElement->SetText(2, Utf82T(it->strDb.c_str()).c_str());
		pListElement->SetText(3, Utf82T(it->strUser.c_str()).c_str());
		pListElement->SetText(4, Utf82T(it->strInfo.c_str()).c_str());;
		TString strPort;
		TCHAR tcPort[10];
		 _itow(it->nTime, tcPort, 10);
		pListElement->SetText(5, tcPort);
	}

效果图

 

解决方案

在找到List之后也动态添加一个ListHeader;xml中可以将ListHeader删除,或者不删除都是可以的;如果是CListTextElementUI

,CListTextElementUI的添加需要在SetText调用之前

 

        CListUI * pList = static_cast<CListUI*>(m_PaintManager.FindControl(_T("ShowList")));
	//pList->RemoveAll();

	CListHeaderUI * pHeader = new CListHeaderUI;  //此处添加新的CListHeaderUI
	pList->Add(pHeader);

	//CListHeaderUI *pHeader = static_cast<CListHeaderUI*>(m_PaintManager.FindControl(_T("Listheader")));
	CListHeaderItemUI *pListHeaderItemIP = new CListHeaderItemUI;
	pListHeaderItemIP->ApplyAttributeList(_T("text=\"IP\"   width=\"100\"  height=\"30\" sepwidth=\"1\""  ));

	CListHeaderItemUI *pListHeaderItemCmd = new CListHeaderItemUI;
	pListHeaderItemCmd->ApplyAttributeList(_T("text=\"Command\"   width=\"100\"  height=\"30\" sepwidth=\"1\"" ));

	CListHeaderItemUI *pListHeaderItemDb = new CListHeaderItemUI;
	pListHeaderItemDb->ApplyAttributeList(_T("text=\"DbName\"   width=\"100\"  height=\"30\" sepwidth=\"1\"" ));

	CListHeaderItemUI *pListHeaderItemUser = new CListHeaderItemUI;
	pListHeaderItemUser->ApplyAttributeList(_T("text=\"User\"   width=\"100\"  height=\"30\" sepwidth=\"1\"" ));

	CListHeaderItemUI *pListHeaderItemInfo = new CListHeaderItemUI;
	pListHeaderItemInfo->ApplyAttributeList(_T("text=\"Info\" itemendellipsis=\"true\"  width=\"100\"  height=\"30\" sepwidth=\"1\"" ));

	CListHeaderItemUI *pListHeaderItemTime = new CListHeaderItemUI;
	pListHeaderItemTime->ApplyAttributeList(_T("text=\"Time\"   width=\"100\"  height=\"30\" sepwidth=\"1\"" ));

	pList->Add(pListHeaderItemIP);
	pList->Add(pListHeaderItemCmd);
	pList->Add(pListHeaderItemDb);
	pList->Add(pListHeaderItemUser);
	pList->Add(pListHeaderItemInfo);
	pList->Add(pListHeaderItemTime);

	//pList->Add(pHeader);
	for(VEC_MYSQLSYSINFO_ITOR it = vecsysinfo.begin(); it != vecsysinfo.end(); it++ )
	{
		CListTextElementUI *pListElement = new CListTextElementUI;
		//pListElement->ApplyAttributeList(_T("textcolor=\"#FF000000\""));
		pList->Add(pListElement);
		pListElement->SetText(0,Utf82T(it->strHost.c_str()).c_str());
		pListElement->SetText(1, Utf82T(it->strCmd.c_str()).c_str());
		pListElement->SetText(2, Utf82T(it->strDb.c_str()).c_str());
		pListElement->SetText(3, Utf82T(it->strUser.c_str()).c_str());
		pListElement->SetText(4, Utf82T(it->strInfo.c_str()).c_str());;
		TString strPort;
		TCHAR tcPort[10];
		 _itow(it->nTime, tcPort, 10);
		pListElement->SetText(5, tcPort);
	}


修复效果图

 

关于CListTextElementUI 如果是没有 添加CListHeaderUI 是无法显示的, 而且在使用的时候一定需要先添加到CListUI中, 否则无法显示;

 

1、

        void CListTextElementUI::SetText(int iIndex, LPCTSTR pstrText)
    	{
		if( m_pOwner == NULL ) return;//如果没有父类直接返回, 无法设置值

		TListInfoUI* pInfo = m_pOwner->GetListInfo();
		if( iIndex < 0 || iIndex >= pInfo->nColumns ) return;//如果iIndex小于0或者如果nColumns==0 (也就是没有任何Header),  超过Header 的索引部分无法设置
		while( m_aTexts.GetSize() < pInfo->nColumns ) { m_aTexts.Add(NULL); }

		CDuiString* pText = static_cast<CDuiString*>(m_aTexts[iIndex]);
		if( (pText == NULL && pstrText == NULL) || (pText && *pText == pstrText) ) return;

		if ( pText ) {delete pText; pText = NULL;}
		m_aTexts.SetAt(iIndex, new CDuiString(pstrText));

		Invalidate();
	}



	bool CListUI::Add(CControlUI* pControl)
	{
		// Override the Add() method so we can add items specifically to
		// the intended widgets. Headers are assumed to be
		// answer the correct interface so we can add multiple list headers.
		if( pControl->GetInterface(_T("ListHeader")) != NULL ) {
			if( m_pHeader != pControl && m_pHeader->GetCount() == 0 ) {
				CVerticalLayoutUI::Remove(m_pHeader);
				m_pHeader = static_cast<CListHeaderUI*>(pControl);
			}
			m_ListInfo.nColumns = MIN(m_pHeader->GetCount(), UILIST_MAX_COLUMNS);
			return CVerticalLayoutUI::AddAt(pControl, 0);
		}
		// We also need to recognize header sub-items
		if( _tcsstr(pControl->GetClass(), _T("ListHeaderItemUI")) != NULL ) {
			bool ret = m_pHeader->Add(pControl);
			m_ListInfo.nColumns = MIN(m_pHeader->GetCount(), UILIST_MAX_COLUMNS);
			return ret;
		}
		// The list items should know about us
		IListItemUI* pListItem = static_cast<IListItemUI*>(pControl->GetInterface(_T("ListItem")));
		if( pListItem != NULL ) {
			pListItem->SetOwner(this);
			pListItem->SetIndex(GetCount());
		}
		return m_pList->Add(pControl);
	}

 

2、

        void CListContainerElementUI::SetPos(RECT rc, bool bNeedInvalidate)
	{	
		CHorizontalLayoutUI::SetPos(rc, bNeedInvalidate);
		if( m_pOwner == NULL ) return;
		UINT uListType = m_pOwner->GetListType();
		if(uListType != LT_LIST && uListType != LT_TREE) return;

		CListUI* pList = static_cast<CListUI*>(m_pOwner);

 		if (uListType == LT_TREE)
 		{
 			pList = (CListUI*)pList->CControlUI::GetInterface(_T("List"));
			if (pList == NULL) return;
 		}
	
		CListHeaderUI *pHeader = pList->GetHeader();
		if (pHeader == NULL || !pHeader->IsVisible()) return;
		int nCount = m_items.GetSize();
		for (int i = 0; i < nCount; i++)
		{
			CControlUI *pListItem = static_cast<CControlUI*>(m_items[i]);
			CControlUI *pHeaderItem = pHeader->GetItemAt(i);
			if (pHeaderItem == NULL) return;
			RECT rcHeaderItem = pHeaderItem->GetPos();
			if (pListItem != NULL && !(rcHeaderItem.left ==0 && rcHeaderItem.right ==0) )
			{
				RECT rt = pListItem->GetPos();
				rt.left = rcHeaderItem.left;
				rt.right = rcHeaderItem.right;
				pListItem->SetPos(rt);
			}
		}
	}

 3、

class UILIB_API CListElementUI : public CControlUI, public IListItemUI
	{
	public:
		CListElementUI();

		LPCTSTR GetClass() const;
		UINT GetControlFlags() const;
		LPVOID GetInterface(LPCTSTR pstrName);

		void SetEnabled(bool bEnable = true);

		int GetIndex() const;
		void SetIndex(int iIndex);

		IListOwnerUI* GetOwner();
		void SetOwner(CControlUI* pOwner);
		void SetVisible(bool bVisible = true);

		bool IsSelected() const;
		bool Select(bool bSelect = true);
		bool SelectMulti(bool bSelect = true);
		bool IsExpanded() const;
		bool Expand(bool bExpand = true);

		void Invalidate(); // 直接CControl::Invalidate会导致滚动条刷新,重写减少刷新区域
		bool Activate();

		void DoEvent(TEventUI& event);
		void SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue);

		void DrawItemBk(HDC hDC, const RECT& rcItem);

	protected:
		int m_iIndex;
		bool m_bSelected;
		UINT m_uButtonState;
		IListOwnerUI* m_pOwner;
	};


	/
	//

	class UILIB_API CListLabelElementUI : public CListElementUI
	{
		DECLARE_DUICONTROL(CListLabelElementUI)
	public:
		CListLabelElementUI();

		LPCTSTR GetClass() const;
		LPVOID GetInterface(LPCTSTR pstrName);

		void DoEvent(TEventUI& event);
		SIZE EstimateSize(SIZE szAvailable);
		void DoPaint(HDC hDC, const RECT& rcPaint);

		void DrawItemText(HDC hDC, const RECT& rcItem);
	};

从1处源码分析 TListInfoUI* pInfo = m_pOwner->GetListInfo();  通过IListOwnerUI*  m_pOwner 获取是否添加了Header,  添加了Header, 但是ListHeader 中没有添加任何一个 ListHeaderItemUI , 因此在1,2处代码中, 都有用到的m_ListInfo.nColumns 就为0, 因此在CListTextElementUI  类中的SetText 直接返回,所以表现没有结果显示,  CListContainerElementUI 在SetPos中也是如此。

从CListContainerElementUI 的SetPos中也可以看出, 其和CListTextElementUI 是一样的;但是从源码中看CListLabelElementUI, 由于继承自CListElementUI 这两个类中都没有接口中指定一定需要Header,其实只是一个简单控件,所以不需要头,Add到List都是可以正常显示的。

总结

CListHeaderUI * pHeader = new CListHeaderUI;添加列表头

CListHeaderItemUI *pListHeaderItemUser = new CListHeaderItemUI; 添加列表头项目

CListTextElementUI *pListElement = new CListTextElementUI;添加列表行

pList->Add(pListHeaderItemIP);将这些元素添加到列表;所有的都是添加到List;虽然列表头项目感觉应该添加到CListHeaderUI,实际上不是,添加进去之后,如果是先将CListHeaderUI添加到CListUI(这样后面添加的行元素就没有添加到CListUI中,显示是显示的CListUI,所以结果是显示了空白,可以看到行,但是看不到值),得到的结果也是CListTextElementUI元素显示是空的;所以动态添加元素的顺序相对重要(其实也就是结构,必须将结构弄清楚)。


 

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 20
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 20
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值