WxTreeCtrl

From WxWiki

Jump to: navigation, search

A tree control presents information as a hierarchy, with items that may be expanded to show further items.

[edit] Iterating through all items in the wxTreeCtrl

I had the need to iterate through all the items, including children and siblings, in a tree, and search for some text. I ended up writing recursive code.

wxTreeCtrl Recursive Access
wxTreeItemId CMyDialog::FindItem( wxTreeItemId root, const wxString& sSearchFor )
{
	wxTreeItemIdValue cookie;
	wxTreeItemId search;
	wxTreeItemId item = m_ctlTreeCtrl->GetFirstChild( root, cookie );
	wxTreeItemId child;
 
	while( item.IsOk() )
	{
		wxString sData = m_ctlTreeCtrl->GetItemText(item);
		if( sSearchFor.CompareTo(sData) == 0 )
		{
			return item;
		}
		if( m_ctlTreeCtrl->ItemHasChildren( item ) )
		{
			wxTreeItemId search = FindItem( item, sSearchFor );
			if( search.IsOk() )
			{
				return search;
			}
		}
		item = m_ctlTreeCtrl->GetNextChild( root, cookie);
	}
 
	/* Not found */
	wxTreeItemId dummy;
	return dummy;
}

As an alternative, you could use the code below:

wxTreeCtrl Recursive Tree Item String Search
wxTreeItemId findTreeItem(wxTreeCtrl* pTreeCtrl, const wxTreeItemId& root, const wxString& text, bool bCaseSensitive, bool bExactMatch)
{
	wxTreeItemId item=root, child;
	wxTreeItemIdValue cookie;
	wxString findtext(text), itemtext;
	bool bFound;
	if(!bCaseSensitive) findtext.MakeLower();
 
	while(item.IsOk())
	{
		itemtext = pTreeCtrl->GetItemText(item);
		if(!bCaseSensitive) itemtext.MakeLower();
		bFound = bExactMatch ? (itemtext == findtext) : itemtext.Contains(findtext);
		if(bFound) return item;
		child = pTreeCtrl->GetFirstChild(item, cookie);
		if(child.IsOk()) child = findTreeItem(pTreeCtrl, child, text, bCaseSensitive, bExactMatch);
		if(child.IsOk()) return child;
		item = pTreeCtrl->GetNextSibling(item);
	} // while(item.IsOk())
 
	return item;
}
Example usage of the wxTreeCtrl String Search
void MyDialog::findMessage(wxCommandEvent& e)
{
	wxArrayTreeItemIds Selections;
	wxTreeItemId item;
	wxTreeItemIdValue cookie;
 
	// fill wxString m_search, bool m_bCaseSensitive, m_bExactMatch from an external source/dialog before this
 
	if(m_search.IsEmpty()) return;
	if(m_TreeCtrl->GetSelections(Selections)) item = Selections[0];
	else item=m_TreeCtrl->GetFirstChild(m_TreeCtrl->GetRootItem(), cookie);
	if(!m_TreeCtrl->GetCount()) return; // empty tree control - i.e. just cleared it?
	item = findTreeItem(m_TreeCtrl, item, m_search, m_bCaseSensitive, m_bExactMatch);
	if(!item.IsOk()) return;
 
	// found an item
	m_TreeCtrl->UnselectAll();
	m_TreeCtrl->SelectItem(item, true);
	m_TreeCtrl->EnsureVisible(item);
 
	return;
}


An alternative non-recursive way of finding an element
wxTreeItemId FindItemNamed(wxTreeCtrl &tree, const std::wstring &name)
{
	std::stack<wxTreeItemId> items;
	if (tree->GetRootItem().IsOk())
		items.push(tree->GetRootItem());
 
	while (!items.empty())
	{
		wxTreeItemId next = items.top();
		items.pop();
 
		if (next != tree->GetRootItem() && tree->GetItemText(next) == name)
			return next;
 
		wxTreeItemIdValue cookie;
		wxTreeItemId nextChild = tree->GetFirstChild(next, cookie);
		while (nextChild.IsOk())
		{
			items.push(nextChild);
			nextChild = tree->GetNextSibling(nextChild);
		}
	}
 
	return wxTreeItemId();
}


[edit] Using Connect() with wxTreeCtrl

Just in case you're trying to guess what these events are named, based on the macros.

wxTreeEvent types:

   wxEVT_COMMAND_TREE_BEGIN_DRAG
   wxEVT_COMMAND_TREE_BEGIN_RDRAG
   wxEVT_COMMAND_TREE_BEGIN_LABEL_EDIT
   wxEVT_COMMAND_TREE_END_LABEL_EDIT
   wxEVT_COMMAND_TREE_DELETE_ITEM
   wxEVT_COMMAND_TREE_GET_INFO
   wxEVT_COMMAND_TREE_SET_INFO
   wxEVT_COMMAND_TREE_ITEM_EXPANDED
   wxEVT_COMMAND_TREE_ITEM_EXPANDING
   wxEVT_COMMAND_TREE_ITEM_COLLAPSED
   wxEVT_COMMAND_TREE_ITEM_COLLAPSING
   wxEVT_COMMAND_TREE_SEL_CHANGED
   wxEVT_COMMAND_TREE_SEL_CHANGING
   wxEVT_COMMAND_TREE_KEY_DOWN
   wxEVT_COMMAND_TREE_ITEM_ACTIVATED
   wxEVT_COMMAND_TREE_ITEM_RIGHT_CLICK
   wxEVT_COMMAND_TREE_ITEM_MIDDLE_CLICK
   wxEVT_COMMAND_TREE_END_DRAG
   wxEVT_COMMAND_TREE_STATE_IMAGE_CLICK
Personal tools