您的位置:首页 > 产品设计 > UI/UE

CListUI的改造--支持checkbox

2015-11-02 16:38 399 查看
参考:/article/3599725.html

注意:

此处需要将内嵌控件的ListHeaderItem 添加一个inset属性,控制内嵌的控件不要铺满整个ListHeaderItem ,否则表头拖动不了,如:

ListHeaderItem text="" inset="1,0,1,0"

这个注意其实很容易被遗忘,而且duidisigner并不会把inset属性给保存到xml里去,这里用代码内置进去,在CListHeaderItemUI的构造函数里添加代码:

CListHeaderItemUI::CListHeaderItemUI() : m_bDragable(true), m_uButtonState(0), m_iSepWidth(4),
m_uTextStyle(DT_VCENTER | DT_CENTER | DT_SINGLELINE), m_dwTextColor(0), m_iFont(-1), m_bShowHtml(false)
{
//设置内边距,防止遮挡拖放的间隔条
RECT rcInset = GetInset();
if ( rcInset.left==0 || rcInset.right==0 ) {
SetInset(CDuiRect(4, 0, 4, 0));
}

SetTextPadding(CDuiRect(2, 0, 2, 0));
ptLastMouse.x = ptLastMouse.y = 0;
SetMinWidth(16);
}


这个好处是,如果xml里配置了且左右边距不为0则不会设置,否则会设置一下,这里边距设置为4,足够拖放用的了。

但是后面的改造有点复杂。。。。

后来看到树控件是支持checkbox的:



在xml里找到关于checkbox的属性:checkboxattr,搜索源代码:

voidCTreeNodeUI::SetAttribute( LPCTSTR pstrName, LPCTSTR pstrValue )
{
if(_tcscmp(pstrName, _T("text")) == 0 )
pItemButton->SetText(pstrValue);
elseif(_tcscmp(pstrName, _T("horizattr")) == 0 )
pHoriz->ApplyAttributeList(pstrValue);
elseif(_tcscmp(pstrName, _T("dotlineattr")) == 0 )
pDottedLine->ApplyAttributeList(pstrValue);
elseif(_tcscmp(pstrName, _T("folderattr")) == 0 )
pFolderButton->ApplyAttributeList(pstrValue);
elseif(_tcscmp(pstrName, _T("checkboxattr")) == 0 )
pCheckBox->ApplyAttributeList(pstrValue);


类CTreeNodeUI继承自CListContainerElementUI,而这个也同样是list控件里显示元素内容的容器。

那就好办了,可以把派生类里的有关checkbox的东西全部搬到基类里实现,这样无论是list还是tree都能用了,妥妥的。

修改好后:



发现checkbox在最前面了,因为我们在基类CListContainerElementUI的构造函数中,最先添加的checkbox。

在派生类中先移除之,后添加:

m_pHoriz->Remove(m_pCheckBox);

m_pHoriz->Add(pDottedLine);

m_pHoriz->Add(pFolderButton);

m_pHoriz->Add(m_pCheckBox);

m_pHoriz->Add(pItemButton);

运行崩溃:



我们看移除函数:

bool CContainerUI::Remove(CControlUI* pControl)
{
if( pControl == NULL) returnfalse;

for( int it = 0; it < m_items.GetSize(); it++ ) {
if( static_cast<CControlUI*>(m_items[it]) == pControl ) {
NeedUpdate();
if( m_bAutoDestroy ) {
if( m_bDelayedDestroy && m_pManager ) m_pManager->AddDelayedCleanup(pControl);
elsedelete pControl;
}
return m_items.Remove(it);
}
}
returnfalse;
}


void CControlUI::NeedUpdate()
{
if( !IsVisible() ) return;
m_bUpdateNeeded = true;
Invalidate();

if( m_pManager != NULL ) m_pManager->NeedUpdate();
}


remove函数会导致控件被刷新,所以在移除前先设置不可见,移除后再设置回去。

原代码:

pHoriz->Add(pDottedLine);
pHoriz->Add(pFolderButton);
pHoriz->Add(pCheckBox);
pHoriz->Add(pItemButton);
Add(pHoriz);


修改后:

bool bVisible = m_pHoriz->IsVisible();    //保存bool bAutoDestroy = m_pHoriz->IsAutoDestroy();
m_pHoriz->SetVisible(false);
m_pHoriz->SetAutoDestroy(false);
m_pHoriz->Remove(m_pCheckBox);
m_pHoriz->SetAutoDestroy(bAutoDestroy);//设置回之前的状态
m_pHoriz->SetVisible(bVisible);
m_pHoriz->Add(pDottedLine);
m_pHoriz->Add(pFolderButton);
m_pHoriz->Add(m_pCheckBox);
m_pHoriz->Add(pItemButton);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: