I am coding the wxWidgets GUI, which includes the dynamic addition and removal of lines of controls inside a grid through buttons.
Each line of controls has a delete button that fires an event that:
- Removes controls from your sizer
- Hides controls
- Disables button event
- Flags of controls available in pools of reusable controls (I reuse controls because wxWidgets doesn't like deleting files at runtime)
Now I don’t think that turning off an event inside an event handler is good. Is there a better way to achieve this behavior?
this is how i dynamically create my controls
bool filtermanager::add()
{
if (!grid || !box || !form || !bsizer)
return false;
dbgcode(log->d(tag, "add: adding a new filter row"));
filter *flt = new filter(this, box, grid);
filters[flt->removebutton()->GetId()] = flt;
refreshlayout();
return true;
}
filtermanager::filter::filter(filtermanager *parent,
wxStaticBox *box, wxGridSizer *grid)
: parent(parent), grid(grid)
{
controlpool *ctl = parent->ctl;
property = ctl->makeComboBox(box, "property");
value = ctl->makeTextCtrl(box, "value");
button = ctl->makeButton(box, "Remove");
grid->SetRows(grid->GetRows() + 1);
grid->Add(property, 0, wxALL | wxEXPAND, 0);
grid->Add(value, 0, wxALL | wxEXPAND, 0);
grid->Add(button, 0, wxALL | wxEXPAND, 0);
button->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &filtermanager::OnRemoveClicked, parent);
}
this is an event handler:
void filtermanager::OnRemoveClicked(wxCommandEvent &e)
{
wxButton *b = dynamic_cast<wxButton *>(e.GetEventObject());
filter *flt = filters[b->GetId()];
dbgcode(log->d(tag,
strfmt() << "OnRemoveClicked: remove button event caught" <<
" property=" << flt->propertycombo() <<
" value=" << flt->valuetext() <<
" button=" << flt->removebutton())
);
removebyflt(flt);
}
void filtermanager::removebyflt(filter *flt)
{
int id = flt->id();
delete filters[id];
filters[id] = NULL;
filters.erase(id);
}
filtermanager::filter::~filter()
{
controlpool *ctl = parent->ctl;
button->Unbind(wxEVT_COMMAND_BUTTON_CLICKED, &filtermanager::OnRemoveClicked, parent);
if (!grid->Detach(property))
parent->log->e(tag, "~filter: failed to remove property from sizer");
if (!grid->Detach(value))
parent->log->e(tag, "~filter: failed to remove value from sizer");
if (!grid->Detach(button))
parent->log->e(tag, "~filter: failed to remove button from sizer");
grid->SetRows(grid->GetRows() - 1);
parent->refreshlayout();
ctl->free(property);
ctl->free(value);
ctl->free(button);
}
, GUI XML.