有什么方法可以使可编辑的
CTreeCtrl
项目适合确切的条件,而不是所有树项目。
如果我设置
TVS_EDITLABELS
,所有树项目都可以通过右键单击来更改
CViewTree m_ModelTree; // CViewTree based on CTreeCtrl
const DWORD dwViewStyle = WS_CHILD | WS_VISIBLE | TVS_HASLINES | TVS_LINESATROOT | TVS_HASBUTTONS | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | TVS_EDITLABELS;
if (!m_ModelTree.Create(dwViewStyle, rectDummy, this, IDC_TREEMODEL))
{
TRACE0(_T("Failed to create Class View\n"));
return -1; // fail to create
}
我只需要编辑确切类型的节点。像这样的东西:
HTREEITEM item = m_ModelTree.GetSelectedItem();
auto it = theApp.TreeMap.find(item);
if (it == theApp.TreeMap.end()) return;
if(it->type == tree_node_type::indexes)
m_ModelTree.EditLabel(hItem);
else
//FORBID EDIT
或者也许有办法禁止在
TV_INSERTSTRUCT
步骤上使用 InsertItem
编辑标签...?
TV_INSERTSTRUCT tvinsert;
m_ModelTree.InsertItem(&tvinsert);
带有 TVS_EDITLABELS
样式的标准
Tree View控件允许客户端在运行时控制是否可以编辑任何给定的项目。这是以发送到控件父级的
TVN_BEGINLABELEDIT
通知的形式提供的,其中返回值确定是否应取消编辑。
文档中的MFC条目Tree Control Label Editing提供了详细信息:
当标签编辑开始时,树控件会发送一条
通知消息。 通过处理此通知,您可以允许编辑某些标签并阻止编辑其他标签。返回 0 允许编辑,返回非零则阻止编辑。TVN_BEGINLABELEDIT
要接收
TVN_BEGINLABELEDIT
通知,控件父级(可能是对话框或常规窗口)必须在其消息映射中有一个条目,用于将通知连接到回调函数。 ON_NOTIFY
宏是最方便的方法:
BEGIN_MESSAGE_MAP(CMyDialog, CDialogEx)
// ...
ON_NOTIFY(TVN_BEGINLABELEDIT, IDC_TREEMODEL, OnTCBeginLabelEdit)
END_MESSAGE_MAP()
OnTCBeginLabelEdit
回调必须具有以下签名:
afx_msg void OnTCBeginLabelEdit(NMHDR* pNotifyStruct, LRESULT* result);
它的实现是决定是否取消编辑的逻辑所在:
void CMyDialog::OnTCBeginLabelEdit(NMHDR* pNotifyStruct, LRESULT* result) {
// The TVN_BEGINLABELEDIT notification sends an NMTVDISPINFO structure
auto const& disp_info = *reinterpret_cast<NMTVDISPINFO*>(pNotifyStruct);
// Get the target item
auto const current_item = disp_info.item.hItem;
// Implement the logic here
bool do_cancel = ...;
// Pass the decision through result
*result = do_cancel;
}
上面假设树视图控件是一个名为
CMyDialg
的对话框的子级,该对话框派生自 CDialogEx
。这些是唯一需要相应调整的部分。