wxTreeCtrl context menu

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
Post Reply
sigipa
In need of some credit
In need of some credit
Posts: 3
Joined: Wed Mar 13, 2019 2:43 am

wxTreeCtrl context menu

Post by sigipa »

Hello All,

I'm having some trouble getting a context menu event to fire with the wxTreeCtrl. I'm actually using a wxGenericDirCtrl and getting the tree from it. I've included the relevant code below. I'm new to wxWidgets, so perhaps I'm doing something stupid. Any advice would be much appreciated.

Code: Select all

   
   
      fileTree = new wxGenericDirCtrl(this, ID_FileTree, wxDirDialogDefaultFolderStr,
      wxDefaultPosition,
      wxSize(200, 150),
      wxDIRCTRL_3D_INTERNAL | wxSUNKEN_BORDER,
      wxEmptyString, 
      0,
      "test");

    Connect(ID_FileTree, wxEVT_DIRCTRL_SELECTIONCHANGED, wxCommandEventHandler(MainFrame::OnFolderSelect));
    Connect(ID_FileTree, wxEVT_DIRCTRL_FILEACTIVATED, wxCommandEventHandler(MainFrame::OnFileSelect));
    wxTreeCtrl  *tree = fileTree->GetTreeCtrl();
    tree->Connect(ID_Tree, wxEVT_TREE_ITEM_RIGHT_CLICK, wxTreeEventHandler(MainFrame::OnTreeItemMenu));
    tree->Connect(ID_Tree, wxEVT_TREE_ITEM_MENU, wxTreeEventHandler(MainFrame::OnTreeItemMenu));
    tree->Connect(ID_Tree, wxEVT_CONTEXT_MENU, wxTreeEventHandler(MainFrame::OnTreeItemMenu));
    ...
    
    
  void MainFrame::OnTreeItemMenu(wxTreeEvent& evt)
  {
    wxTreeCtrl *tree = fileTree->GetTreeCtrl();


    messages->AppendText("OnTreeItemMenu\n");

    // This event handler creates a new menu and displays
    // it as a popup menu with the wxWindow::PopupMenu function

    wxMenu menu;
    menu.Append(ID_TreePermissions, "Show node text");

    // We need to pass some data (the text of the node) to
    // the menu event handler. We create a class that holds
    // the needed data and use the Connect function to
    // associate our event handler with the menu.
    UserData* userData = new UserData();
    userData->data = tree->GetItemText(evt.GetItem());
    menu.Connect(ID_TreePermissions, wxEVT_MENU,
      (wxObjectEventFunction)&MainFrame::OnMenuItem,
      userData, this);

    // Display the menu as a popup menu
    PopupMenu(&menu);

    evt.Skip();
  }
     
    
Thanks,
-S
sigipa
In need of some credit
In need of some credit
Posts: 3
Joined: Wed Mar 13, 2019 2:43 am

Re: wxTreeCtrl context menu

Post by sigipa »

Hello All,

I figured this out. The tree used by the wxGenericDirCtrl did not have an id set. setting the tree id solved the issue.

Thanks,
-S
sigipa
In need of some credit
In need of some credit
Posts: 3
Joined: Wed Mar 13, 2019 2:43 am

Re: wxTreeCtrl context menu

Post by sigipa »

Hello All,

Okay. There was one more little wrinkle. When I set the tree id, it broke the wxGenericDirCtrl event handling. Apparently, the wxGenericDirCtrl sets an id for the tree itself. The correct thing to do was to just call GetId() on the tree and use that to connect the handler. I've included the code snippet below, to help anyone else that may run into this.



Code: Select all

 wxTreeCtrl  *tree = fileTree->GetTreeCtrl();
  Connect(tree->GetId(), wxEVT_TREE_ITEM_RIGHT_CLICK, wxTreeEventHandler(MainFrame::OnTreeItemMenu));
  Connect(tree->GetId() wxEVT_TREE_ITEM_MENU, wxTreeEventHandler(MainFrame::OnTreeItemMenu));
  Connect(tree->GetId(), wxEVT_CONTEXT_MENU, wxTreeEventHandler(MainFrame::OnTreeItemMenu));
Thanks,
-S
ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 7477
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: wxTreeCtrl context menu

Post by ONEEYEMAN »

Hi,
2 things:

1. In the new code it is strongly recommended to use Bind() instead of Connect(). Connect() should be used only for backward compatibility.
2. You don't need to assign Id to anything if you are not using event table.

Code: Select all

m_treeCtrl->Bind( wxEVT_TREE_ITEM_RIGHT_CLICK, &MainFrame::OnTreeItemMenu, this );
if this code is inside MainFrame class method.

As you can see it is much less typing and Bind() is more error prone as it can give you an error during compilation time.

Thank you.
Post Reply