duilib 自带树形控件的认识
CTreeViewUI
1、該控件繼承自CListUI,所以是使用了對應(yīng)的列表來模擬樹形控件。該控件的容器填裝的是CTreeNodeUI,而CTreeNodeUI也繼承CListContainerElementUI,所以樹形控件剝掉外殼其實(shí)就是CListUI,然后子列表是CListContainerElementUI。
2、a.每個屬性控件包含的節(jié)點(diǎn):擴(kuò)展按鈕點(diǎn)前面的空格、擴(kuò)展按鈕、checkbox按鈕、空格 再加上 后面的用戶自添元素。所有元素加起來的寬度是250,也就是說如果該樹形控件比較大的話就會出現(xiàn)太窄而無法容下所有元素的現(xiàn)象。所以這里可以根據(jù)自身的需要進(jìn)行相應(yīng)的調(diào)整。如代碼UITreeView.cpp的第32行:this->SetFixedWidth(250);
b.樹形控件的每個節(jié)點(diǎn)的擴(kuò)展按鈕前面的空白如何計算呢?如代碼的UITreeView.cpp的第48行:pDottedLine->SetFixedWidth(_ParentNode->GetDottedLine()->GetFixedWidth()+16); 通過獲取父節(jié)點(diǎn)的寬度再加上16。如果父節(jié)點(diǎn)是空則使用默認(rèn)的2.雖然這里有默認(rèn)的了,但是在添加childnode的時候會更新空白寬度調(diào)用CalLocation
3、節(jié)點(diǎn)相關(guān)屬性的設(shè)置則可以看對應(yīng)的void CTreeNodeUI::SetAttribute( LPCTSTR pstrName, LPCTSTR pstrValue )函數(shù)的設(shè)置。再根據(jù)我第二點(diǎn)的描述則可以簡單應(yīng)用。
?
4、關(guān)于樹形控件子樹的打開跟關(guān)閉。這里使用的是剛開始的時候默認(rèn)全部是打開的。是因?yàn)槊總€控件默認(rèn)是全部打開的。雖然是打開的,但是每個擴(kuò)展按鈕默認(rèn)都是check=false,所以在放圖片的時候注意這個foldattr屬性normalimage跟selectedimage。
如果在程序開始運(yùn)行的時候不想讓每個控件都打開,只想讓部分控件打開則需要修改樹形控件的程序。修改的位置是在bool CTreeNodeUI::Add( CControlUI* _pTreeNodeUI ),該函數(shù)是在UIDlgBuilder進(jìn)行解析xml函數(shù)的時候直接調(diào)用的函數(shù)。這里我嘗試將selected="true" 進(jìn)行設(shè)置發(fā)現(xiàn)只是圖標(biāo)修改了而子樹還顯示著。
所以這里我在Add函數(shù)調(diào)用的CTreeNodeUI::AddChildNode的第370行添加了
// 這里使用?!this->IsVisible()是如果本父節(jié)點(diǎn)是非可見了那么它對應(yīng)的子樹也應(yīng)該是不可見的。
if (pFolderButton->IsSelected() || !this->IsVisible())
SetItemExpand(this);
并寫了SetItemExpand函數(shù),該函數(shù)我是抄襲對應(yīng)的CTreeViewUI的SetItemExpand
void CTreeNodeUI::SetItemExpand( CTreeNodeUI* _TreeNode ){if(_TreeNode){if(_TreeNode->GetCountChild() > 0){int nCount = _TreeNode->GetCountChild();for(int nIndex = 0;nIndex < nCount;nIndex++){CTreeNodeUI* pItem = _TreeNode->GetChildNode(nIndex);pItem->SetVisible(false);if(pItem->GetCountChild() && !pItem->GetFolderButton()->IsSelected())SetItemExpand(pItem);}}}} View Code這樣,當(dāng)設(shè)置了selected="true"的時候,則相應(yīng)的子樹均為不可見狀態(tài)。
5、對應(yīng)的按鈕響應(yīng)函數(shù):其實(shí)在TreeViewUI的Add函數(shù)中已經(jīng)都有對應(yīng)的顯示了。
bool CTreeViewUI::Add( CTreeNodeUI* pControl )
long CTreeViewUI::AddAt( CTreeNodeUI* pControl, int iIndex )
均已經(jīng)做了相應(yīng)的操作。
但是我們經(jīng)常做這樣子的操作:雙擊樹形控件checkbox右邊的空白區(qū)域然后打開的子樹則會相應(yīng)的關(guān)閉,或者關(guān)閉的子樹則會相應(yīng)的打開。(即修改對應(yīng)的foldattr的selected參數(shù)的值)。
在這里我們這樣子卻做不了。即使像
本身add里面那樣子操作
pControl->OnNotify += MakeDelegate(this,&CTreeViewUI::OnDBClickItem);
pControl->GetFolderButton()->OnNotify += MakeDelegate(this,&CTreeViewUI::OnFolderChanged);
pControl->GetCheckBox()->OnNotify += MakeDelegate(this,&CTreeViewUI::OnCheckBoxChanged);
也是沒辦法獲取到。究其原因得看本身的空白處到底是什么:?COptionUI();
而看其對應(yīng)的父控件的CbuttonUI則可以知其一二,里面的onevent對應(yīng)的
if( event.Type == UIEVENT_BUTTONDOWN || event.Type == UIEVENT_DBLCLICK ){if( ::PtInRect(&m_rcItem, event.ptMouse) && IsEnabled() ) {m_uButtonState |= UISTATE_PUSHED | UISTATE_CAPTURED;Invalidate();}return;} View Code只是做了相應(yīng)的圖像更新操作,而沒有發(fā)送對應(yīng)的onnotify double click操作。那如果在button里面添加該操作呢?但是事實(shí)證明在onevent根本捕捉不到對應(yīng)的dbclick,因?yàn)榘粹o是不支持雙擊的。
那到底啥原因呢??
后來我發(fā)現(xiàn)在注冊windowclass的時候
WNDCLASS wc = { 0 };
wc.style = GetClassStyle();
該GetClassStyle是虛函數(shù),可以通過繼承該函數(shù)添加相應(yīng)的style來實(shí)現(xiàn)雙擊的效果。
UINT GetClassStyle() const
{
return CS_DBLCLKS;
};
如果需要使用自己量身定制的樹形控件,可以看對應(yīng)的duilib官方給的demo中的GameDemo。(即自繪樹形控件)
轉(zhuǎn)載于:https://www.cnblogs.com/cxiaoln/p/4396398.html
總結(jié)
以上是生活随笔為你收集整理的duilib 自带树形控件的认识的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [唐诗]野望-王绩
- 下一篇: 构建ASP.NET MVC4+EF5+E