title: wxWidgets: unbind event as its triggered
body: <p>I'm coding a wxWidgets GUI that involves dynamically adding and removing rows of controls inside a gridsizer through buttons. </p>
  
  <p>Each row of controls has a "remove" button that triggers an event that:</p>
  
  <ul>
  <li>Removes the controls from their sizer </li>
  <li>Hides the controls</li>
  <li>Unbinds theremove button event</li>
  <li>Flags the controls as available in the reusable controls pools (I'm
  re-using controls because wxWidgets doesn't like deleting stuff at
  runtime)</li>
  </ul>
  
  <p>Now I don't think unbinding the event inside the event handler itself is a good thing. Is there a better way to achieve this behaviour?</p>
  
  <p>this is how I dynamically create my controls</p>
  
  <pre><code>bool filtermanager::add()
  {
      if (!grid || !box || !form || !bsizer)
          return false;
  
      dbgcode(log-&gt;d(tag, "add: adding a new filter row"));
  
      // add and index filter in the filter map and refresh layout
      filter *flt = new filter(this, box, grid);
      filters[flt-&gt;removebutton()-&gt;GetId()] = flt;
      refreshlayout();
  
      return true;
  }
  
  filtermanager::filter::filter(filtermanager *parent, 
      wxStaticBox *box, wxGridSizer *grid)
      : parent(parent), grid(grid)
  {
      controlpool *ctl = parent-&gt;ctl;
  
      // initialize filter row elements
      property = ctl-&gt;makeComboBox(box, "property");
      value = ctl-&gt;makeTextCtrl(box, "value");
      button = ctl-&gt;makeButton(box, "Remove");
  
      // add filter row to the grid sizer
      grid-&gt;SetRows(grid-&gt;GetRows() + 1);
      grid-&gt;Add(property, 0, wxALL | wxEXPAND, 0);
      grid-&gt;Add(value, 0, wxALL | wxEXPAND, 0);
      grid-&gt;Add(button, 0, wxALL | wxEXPAND, 0);
  
      // bind remove button
      button-&gt;Bind(wxEVT_COMMAND_BUTTON_CLICKED, &amp;filtermanager::OnRemoveClicked, parent);
  }
  </code></pre>
  
  <p>this is the event handler:</p>
  
  <pre><code>void filtermanager::OnRemoveClicked(wxCommandEvent &amp;e)
  {
      wxButton *b = dynamic_cast&lt;wxButton *&gt;(e.GetEventObject());
      filter *flt = filters[b-&gt;GetId()];
  
      dbgcode(log-&gt;d(tag, 
          strfmt() &lt;&lt; "OnRemoveClicked: remove button event caught" &lt;&lt; 
          " property=" &lt;&lt; flt-&gt;propertycombo() &lt;&lt; 
          " value=" &lt;&lt; flt-&gt;valuetext() &lt;&lt; 
          " button=" &lt;&lt; flt-&gt;removebutton())
      );
  
      removebyflt(flt);
  }
  
  void filtermanager::removebyflt(filter *flt)
  {
      int id = flt-&gt;id();
  
      // dealloc filter from the map
      delete filters[id];
      filters[id] = NULL;
      filters.erase(id);
  }
  
  filtermanager::filter::~filter()
  {
      controlpool *ctl = parent-&gt;ctl;
  
      // unbind button
      button-&gt;Unbind(wxEVT_COMMAND_BUTTON_CLICKED, &amp;filtermanager::OnRemoveClicked, parent);
  
      // remove the filter from the gui
      if (!grid-&gt;Detach(property))
          parent-&gt;log-&gt;e(tag, "~filter: failed to remove property from sizer");
  
      if (!grid-&gt;Detach(value))
          parent-&gt;log-&gt;e(tag, "~filter: failed to remove value from sizer");
  
      if (!grid-&gt;Detach(button))
          parent-&gt;log-&gt;e(tag, "~filter: failed to remove button from sizer");
  
      grid-&gt;SetRows(grid-&gt;GetRows() - 1);
  
      // refresh panels as usual
      parent-&gt;refreshlayout();
  
      ctl-&gt;free(property);
      ctl-&gt;free(value);
      ctl-&gt;free(button);
  }
  </code></pre>
  
  <p>By the way, the purpose of this GUI is adding search filters for properties in a loaded XML file.</p>