ボタンを介して gridsizer 内のコントロールの行を動的に追加および削除する wxWidgets GUI をコーディングしています。
コントロールの各行には、次のイベントをトリガーする「削除」ボタンがあります。
- コントロールをサイザーから削除します
- コントロールを非表示にします
- ボタンの削除イベントのバインドを解除します
- コントロールが再利用可能なコントロール プールで使用可能であることを示します (wxWidgets は実行時に何かを削除するのを好まないため、コントロールを再利用しています)。
ここで、イベント ハンドラー自体の中でイベントのバインドを解除することは良いことではないと思います。この動作を達成するためのより良い方法はありますか?
これが、コントロールを動的に作成する方法です
bool filtermanager::add()
{
if (!grid || !box || !form || !bsizer)
return false;
dbgcode(log->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->removebutton()->GetId()] = flt;
refreshlayout();
return true;
}
filtermanager::filter::filter(filtermanager *parent,
wxStaticBox *box, wxGridSizer *grid)
: parent(parent), grid(grid)
{
controlpool *ctl = parent->ctl;
// initialize filter row elements
property = ctl->makeComboBox(box, "property");
value = ctl->makeTextCtrl(box, "value");
button = ctl->makeButton(box, "Remove");
// add filter row to the grid sizer
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);
// bind remove button
button->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &filtermanager::OnRemoveClicked, parent);
}
これはイベント ハンドラです。
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();
// dealloc filter from the map
delete filters[id];
filters[id] = NULL;
filters.erase(id);
}
filtermanager::filter::~filter()
{
controlpool *ctl = parent->ctl;
// unbind button
button->Unbind(wxEVT_COMMAND_BUTTON_CLICKED, &filtermanager::OnRemoveClicked, parent);
// remove the filter from the gui
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);
// refresh panels as usual
parent->refreshlayout();
ctl->free(property);
ctl->free(value);
ctl->free(button);
}
ところで、この GUI の目的は、読み込まれた XML ファイルにプロパティの検索フィルターを追加することです。