duilib在同一个界面中(xml)加载两种自定义的list

一.duilib中list的自定义使用(一个界面中只有一个自定义list)

list是duilib中的基本控件,是一种基本的表格,可以自定义表格的各种基本属性(颜色,边框,字体等),类似于下图的基本效果,显示的是5列7行的一个列表。

1.xml文件的编写

listtest.xml(list列表控件)

<?xml version="1.0" encoding="UTF-8"?>
<Window size="1280,768" caption="0,0,0,36" roundcorner="0,0" >
	<Include source="Default.xml" />
	<VerticalLayout  bkcolor="#FFFFFFFF" >
		<HorizontalLayout height="500" width="1220" inset="20,20,0,0">
			<List name="expenserecordlist" width="1190" height="500" bkcolor="#FFFFFFFF" inset="0,0,0,0" itemshowhtml="true" vscrollbar="true" hscrollbar="true" headerbkimage="file='list_header_bg.png'" itemalign="center" hscrollbar="false" menu="true">
				<ListHeader height="40" menu="true" scaleheader="true" bkcolor="#FFFFFFFF" >
					<ListHeaderItem text="时间"  font="2" scale="17" textcolor="#FF151515" hotimage="file='list_header_hot.png'" pushedimage="file='list_header_pushed.png'" sepimage="file='list_header_sep.png'" sepwidth="1"/>
					<ListHeaderItem text="类型"  font="2" scale="14" textcolor="#FF151515" hotimage="file='list_header_hot.png'" pushedimage="file='list_header_pushed.png'" sepimage="file='list_header_sep.png'" sepwidth="1"/>
					<ListHeaderItem text="金额"  font="2" scale="13" textcolor="#FF151515" hotimage="file='list_header_hot.png'" pushedimage="file='list_header_pushed.png'" sepimage="file='list_header_sep.png'" sepwidth="1"/>
					<ListHeaderItem text="余额"  font="2" scale="13" textcolor="#FF151515" hotimage="file='list_header_hot.png'" pushedimage="file='list_header_pushed.png'" sepimage="file='list_header_sep.png'" sepwidth="1"/>
					<ListHeaderItem text="备注"  font="2" scale="40" textcolor="#FF151515" hotimage="file='list_header_hot.png'" pushedimage="file='list_header_pushed.png'" sepimage="file='list_header_sep.png'" sepwidth="1"/>
				</ListHeader>
			</List>
		</HorizontalLayout>
    </VerticalLayout>
</Window>

listitem.xml(自定义列表中的列)

<?xml version="1.0" encoding="UTF-8"?>
<Window>
	<!-- <Font shared="true" id="1" name="微软雅黑" size="12" default="true" /> -->
	<ListContainerElement>
		<HorizontalLayout height="32">
			<HorizontalLayout width="180">
				<Label name="time"  align="center" valign="center" textcolor="#FF727272" />
			</HorizontalLayout>
			<HorizontalLayout width="220">
				<Label name="type"  align="center" valign="center" textcolor="#FF727272"  />
			</HorizontalLayout>
			<HorizontalLayout width="110">
				<Label name="amount"  align="center" valign="center" textcolor="#FF727272" />
			</HorizontalLayout>
			<HorizontalLayout width="190">
				<Label name="balance"  align="center" valign="center" textcolor="#FF727272" />
			</HorizontalLayout>
			<HorizontalLayout width="490">
				<Label name="remarks"  align="center" valign="center" textcolor="#FF727272" />
			</HorizontalLayout>
		</HorizontalLayout>
   </ListContainerElement>
</Window>

2.代码示例



//往消费记录列表添加节点
bool CTestDialog::AddNodeOfExpenserecordList(const UserExpenseRecordInfo& info)
{
    CListUI* pList = static_cast<CListUI*>(m_PaintManager.FindControl(_T("listtest")));
	if (NULL == pList)
	{
		return false;
	}

	CListContainerElementUI* pListElement = NULL;
	
    //CDialogBuilder m_dlgBuilderExpendList  此处是m_dlgBuilderExpendList  的类型
	if (!m_dlgBuilderExpendList.GetMarkup()->IsValid())
	{
		pListElement = static_cast<CListContainerElementUI*>(m_dlgBuilderExpendList.Create(_T("listitem.xml"), (UINT)0, NULL, &m_PaintManager));
	}
	else
	{
		pListElement = static_cast<CListContainerElementUI*>(m_dlgBuilderExpendList.Create((UINT)0, &m_PaintManager));
	}
	
	if (pListElement == NULL)
	{
		return false;
	}

	CLabelUI* pLab = static_cast<CLabelUI*>(m_PaintManager.FindSubControlByName(pListElement, _T("time")));
	if (pLab != NULL)
	{
		pLab->SetBorderSize(1);
		pLab->SetBorderColor(0xFFBDBDBD);
		pLab->SetFont(2);
		pLab->SetText(info.wstrData.c_str());
	}

	pLab = NULL;
	pLab = static_cast<CLabelUI*>(m_PaintManager.FindSubControlByName(pListElement, _T("type")));
	if (pLab != NULL)
	{
		pLab->SetBorderSize(1);
		pLab->SetBorderColor(0xFFBDBDBD);
		pLab->SetFont(2);
		pLab->SetText(info.wstrType.c_str());
	}

	pLab = NULL;
	pLab = static_cast<CLabelUI*>(m_PaintManager.FindSubControlByName(pListElement, _T("remarks")));
	if (pLab != NULL)
	{
		pLab->SetBorderSize(1);
		pLab->SetBorderColor(0xFFBDBDBD);
		pLab->SetFont(2);
		pLab->SetText(info.wstrRemarks.c_str());
	}

	pLab = NULL;
	pLab = static_cast<CLabelUI*>(m_PaintManager.FindSubControlByName(pListElement, _T("amount")));
	if (pLab != NULL)
	{
		pLab->SetBorderSize(1);
		pLab->SetBorderColor(0xFFBDBDBD);
		pLab->SetFont(2);
		pLab->SetText(info.wstrAmount.c_str());
	}

	pLab = NULL;
	pLab = static_cast<CLabelUI*>(m_PaintManager.FindSubControlByName(pListElement, _T("balance")));
	if (pLab != NULL)
	{
		pLab->SetBorderSize(1);
		pLab->SetBorderColor(0xFFBDBDBD);
		pLab->SetFont(2);
		pLab->SetText(info.wstrBalance.c_str());
	}
	pListElement->SetBorderSize(1);
	pListElement->SetBorderColor(0xFFBDBDBD);
	pListElement->SetFixedWidth(1190);
	pListElement->SetFixedHeight(EXPENSE_RECORD_LIST_ITEM_HEIGH);
	int index = pList->GetCount();
	
	if (!pList->AddAt(pListElement, index))
	{
		delete pListElement;
		
		return false;
	}
	return true;
}

二.一个界面中存在两个或者多个自定义类型的list

   类似于上述例子,是描述的在一个页面中也就是一个xml显示界面中,只存在一个自定义的list控件,假如在一个界面中需要有两种及以上的其他类型的list控件(也就是list的列属性是不同的,如上listitem.xml中配置中的一样,存在多个类型的listitem.xml)

也许我们会直接采用跟上述基本方法一样的做法,只是把配置的xml文件替换一下,我当时也是这样干的。。。,效果是很明显的,明显错误,加载的自定义的列配置文件,总是第一个加载的xml,后续的新的xml文件压根没家在生效。

如何解决这种情况?

经过一段时间的折腾,发现了一个解决方法,关键就在如下代码:

    CListContainerElementUI* pListElement = NULL;
	
	if (!m_dlgBuilderExpendList.GetMarkup()->IsValid())  //m_dlgBuilderExpendList 这才是问题解决点
	{
		pListElement = static_cast<CListContainerElementUI*>(m_dlgBuilderExpendList.Create(_T("ExpenseRecordListItem.xml"), (UINT)0, NULL, &m_PaintManager));
	}
	else
	{
		pListElement = static_cast<CListContainerElementUI*>(m_dlgBuilderExpendList.Create((UINT)0, &m_PaintManager));
	}
	
	if (pListElement == NULL)
	{
		return false;
	}

上述代码段中 m_dlgBuilderExpendLis是问题的解决关键点,下面是m_dlgBuilderExpendLis 的定义:

CDialogBuilder m_dlgBuilderExpendList;

CDialogBuilder是一个duilib的类,可以切换到duilib的源码中看一下具体的各种细节和关联代码,会与更清楚的认识。

对于一个单独的界面,基本都存在对应的xml,每个单独的界面都有一个对应的类,而每一个类需要加载自定义的list的xml文件则必须定义一个CDialogBuilder类对象。

当一个界面(一个类)中需要加载多个自定义的list控件时,针对每一个list控件定义对应的CDialogBuilder对象即可,在代码中载入xml时使用不同的CDialogBuilder类对象即可,代码如下:

类头文件中定义两个CDialogBuilder类对象

private:
CDialogBuilder m_dlgBuilder;    //加载listitem.xml
CDialogBuilder m_dlgBuilderExpendList;   //加载ExpenseRecordListItem.xml
//可以添加多个自定义list控件

在类的是cpp文件中使用

CListContainerElementUI* pListElement = NULL;
	
	if (!m_dlgBuilderExpendList.GetMarkup()->IsValid())
	{
		pListElement = static_cast<CListContainerElementUI*>(m_dlgBuilderExpendList.Create(_T("ExpenseRecordListItem.xml"), (UINT)0, NULL, &m_PaintManager));
	}
	else
	{
		pListElement = static_cast<CListContainerElementUI*>(m_dlgBuilderExpendList.Create((UINT)0, &m_PaintManager));
	}
	
	if (pListElement == NULL)
	{
		return false;
	}
CListContainerElementUI* pListElement0 = NULL;
	
	if (!m_dlgBuilder.GetMarkup()->IsValid())
	{
		pListElement0 = static_cast<CListContainerElementUI*>(m_dlgBuilder.Create(_T("listitem.xml"), (UINT)0, NULL, &m_PaintManager));
	}
	else
	{
		pListElement0 = static_cast<CListContainerElementUI*>(m_dlgBuilder.Create((UINT)0, &m_PaintManager));
	}

	if (pListElement0 == NULL)
	{
		return;
	}

 

已标记关键词 清除标记
我使用Delete()程序会崩溃。最后发现在 ```for( int it1 = 0; it1 < m_items.GetSize(); it1++ ) { CControlUI* pControl = static_cast<CControlUI*>(m_items[it1]); if( !pControl->IsVisible() ) continue; if( pControl->IsFloat() ) continue; szControlAvailable = szAvailable; RECT rcPadding = pControl->GetPadding(); szControlAvailable.cy -= rcPadding.top + rcPadding.bottom; iControlMaxWidth = pControl->GetFixedWidth(); iControlMaxHeight = pControl->GetFixedHeight(); if (iControlMaxWidth <= 0) iControlMaxWidth = pControl->GetMaxWidth(); if (iControlMaxHeight <= 0) iControlMaxHeight = pControl->GetMaxHeight(); if (szControlAvailable.cx > iControlMaxWidth) szControlAvailable.cx = iControlMaxWidth; if (szControlAvailable.cy > iControlMaxHeight) szControlAvailable.cy = iControlMaxHeight; SIZE sz = { 0 }; if (pControl->GetFixedWidth() == 0) { nAdjustables++; sz.cy = pControl->GetFixedHeight(); } else { sz = pControl->EstimateSize(szControlAvailable); if (sz.cx == 0) { nAdjustables++; } else { if (sz.cx < pControl->GetMinWidth()) sz.cx = pControl->GetMinWidth(); if (sz.cx > pControl->GetMaxWidth()) sz.cx = pControl->GetMaxWidth(); } } cxFixed += sz.cx + pControl->GetPadding().left + pControl->GetPadding().right; sz.cy = MAX(sz.cy, 0); if( sz.cy < pControl->GetMinHeight() ) sz.cy = pControl->GetMinHeight(); if( sz.cy > pControl->GetMaxHeight() ) sz.cy = pControl->GetMaxHeight(); cyNeeded = MAX(cyNeeded, sz.cy + rcPadding.top + rcPadding.bottom); nEstimateNum++; } ``` for循环的第1个判断崩溃,而第一句话pControl的结果全是乱码
©️2020 CSDN 皮肤主题: Age of Ai 设计师:meimeiellie 返回首页