没有合适的资源?快使用搜索试试~ 我知道了~
温馨提示
试读
11页
duilib的CTreeViewUI扩展以支持节点拖放duilib的CTreeViewUI扩展以支持节点拖放duilib的CTreeViewUI扩展以支持节点拖放duilib的CTreeViewUI扩展以支持节点拖放duilib的CTreeViewUI扩展以支持节点拖放duilib的CTreeViewUI扩展以支持节点拖放duilib的CTreeViewUI扩展以支持节点拖放
资源推荐
资源详情
资源评论
由于客户要求能够在树控件中在各个节点间进行节点拖放,此项目是应用 duilib 来实现的,
但找遍了 duilib 的例子以及网上的资料,都没有相关可以拖放的树的信息,这下可难倒我
这个刚入门的 duiliber 了,想来想去,拟定了如下三个探索方向:
1. 嵌入 window 的 TreeView
网上有 MFC 版本的现成的可拖放节点的代码,而 duilib 也能支持嵌入系统控件的功能,
应该是能够通过这种方式实现的,但深入考虑下去,这条路我还是放弃了,原因有二:
1). 找到的代码是 MFC 版本的,要转成 WIN32 API 的版本,还需要较多时间;
2). 即便转换完成,这里还需要通过自绘方式来完成树节点的美化,这恰好是我的短板,
也与使用 duilib 不符。
2. 在程序中嵌入一个网页,通过 JS 的方式来实现节点拖放
找到网上有相关的 JS 可拖动节点的树的实现,如果能做到与程序的完美 jiāo 互[每一次拖
放节点,均需要将移动过的节点信息保存进本地数据库],这应该是一个不错的办法。
3. 使用 duilib 来进行扩展
从内心来讲,还是希望使用 duilib 来原生的支持拖放功能,这样无论是加入业务 chǔ 理还
是显示效果,都会是最完美的;同时心里又实在没底,担心扩展失败。直到写此文的时候
也不知道目前的状态是不是就已经能够满足要求了,所以第 2 个方案还是作为备选,万一
扩展的方案最终行不通,也至 shao 有可以完成项目的方案。
我所设想的拖放功能,应该是移动 + 拖放效果,而这里的核心应该是在移动上,应该如
何来实现移动呢?
1. 节点的移动
CTreeViewUI 是继承 于 CListUI 的,无论树中的每一个节点 chǔ 于何 层次 ,均 是以
CListUI 中的行数据来呈现的,而每一行则是以 CTreeNodeUI 来呈现。
通过对 CTreeViewUI 及 CTreeNodeUI 的代码分析,以及结合 duilib 的控件指针智能管理
的 chǔ 理,我决定按此思路进一步 chǔ 理:
在要移动一个节点时,分解成 移除 + 添加,移除旧的节点,在新的位置添加此节点[以
及其子节点],那这里就需要做到之前移除节点时,仅是将其从 CListUI 中移除,而不是会
销毁这个节点控件,这样才能保证后续能将其添加到新的位置上。
这里我们注意到 CTreeNodeUI 的 RemoveAt 函数,此函数主要是删除自身的所有子节点,
再 将 自 己 从 树 pTreeView 中 删 除 , 进 而 调 用 CListUI::Remove() , 最 终 落 在
CContainerUI 的删除控件的函数中:
bool CContainerUI::Remove(CControlUI* pControl)
{
if( pControl == NULL) return false;
for( int it = 0; it < m_items.GetSize(); it++ ) {
if( static_cast<CControlUI*>(m_items[it]) == pControl ) {
NeedUpdate();
this;
if( m_bAutoDestroy ) {
if( m_bDelayedDestroy && m_pManager ) m_pManager-
>AddDelayedCleanup(pControl);
else delete pControl;
}
return m_items.Remove(it);
}
}
return false;
}
CContainnerUI 有一个 m_bAutoDestroy 属 xìng,决定它在删除控件的时候是否自动清
理内存,所以我们只要能设置好容器不要帮我们清理内容,这个控件就能得以保存下来,
以供下次使用了。
经过测试跟踪,通过 CtreeViewUI 的 SetAutoDestroy(false);设置容器不自动清理,总
是在 CContainnerUI 的 Remove 函数中发现 m_bAutoDestroy 为 true[默认值],最终
发现是由于 CListBodyUI 的的属 xìng 未正确设置,需要在 CTreeViewUI 中添加如下代码:
void CTreeViewUI::SetAutoDestroy(bool bAuto)
{
m_pList->SetAutoDestroy(bAuto);
__super::SetAutoDestroy(bAuto);
}
解决了控件的生命周期的问题,接下来需要将其添加到具体的位置了,这里需要注意的,
如果被 Move 的节点有子节点,直接将此节点添加到目标节点下是有问题的,他的子节点
将不会显示,此 chǔ 我的做法是针对本节点,以及其所有子节点,逐个添加到新的位置。
为 此 , 我 在 CTreeViewUI 中 添 加 了 一 个 Move 的 函 数 来 总 管 移 动 节 点 , 以 及 在
CTreeNodeUI 中添加了 AddToList 以及 AddNodeFromList 两个函数,这两个函数主要
是完成对被移动节点的子节点的添加[删除时已经被从 CList 中移除]:
void CTreeViewUI::Move(CTreeNodeUI* dstParent, CTreeNodeUI* pNode)
{
if (dstParent == NULL || pNode == NULL)
{
return;
}
CStdPtrArray listNodes;
CTreeNodeUI* srcParent = pNode->GetParentNode();
if (srcParent == NULL)
{
return;
}
pNode->AddToList(listNodes);
SetAutoDestroy(false); //移除前先设置不自动清除
srcParent->Remove(pNode);
SetAutoDestroy(true); //还原默认设置
剩余10页未读,继续阅读
资源评论
- 海贼王大妈2014-06-04可以用,谢谢分享
- tulingwangbo2018-12-20大家不要下这个,一个word文档在这骗粉呢,直接下载http://download.csdn.net/detail/gaoyuyihao/7222955
- thinkhua2015-06-26做windows客户端不错的东西,正好项目中需要用到,谢谢。
- 神在唱歌2017-12-18值得参考,谢谢
- c_razy082018-06-08可以拖放,有鼠标动态提示
gaoyuyihao
- 粉丝: 50
- 资源: 263
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功