Here is what it looks like when first opened: By sticking a Show() in BeginEdit(), clicking on each one gives me what I want: It looks like Create() is not called right away. Rather, it's only called when interacted with. (ie. left-click)
I've tried doing things like this:
Code: Select all
wxGridEvent Ev(pogrid->GetId(), wxEVT_GRID_SELECT_CELL,pogrid,row,col);
pogrid->GetEventHandler()->ProcessEvent(Ev);
Does anyone have any ideas how to either:
1. Get the comboboxes to be Create()d during construction?
2. Use an event to force the comboboxes to be generated?
Thanks for any help you can give. I've included the source code but you can also refer to the EnumEditor. It behaves the same way as mine. Mostly because that's where I got most of the code from.
Code: Select all
mywidgets.h
class DBComboBox : public wxComboBox {
public:
DBComboBox(wxWindow *parent, wxWindowID id,wxString defaultselection,const wxPoint pos, const wxSize size, int style);
void Prime(const wxArrayString *charray,wxArrayString *dataarray);
wxString getid();
void setbyid(wxString id);
};
class WXDLLIMPEXP_ADV DBGridCellChoiceEditor : public wxGridCellChoiceEditor
{
public:
DBGridCellChoiceEditor( const wxArrayString& choices,const wxArrayString &ids );
virtual ~DBGridCellChoiceEditor() {}
virtual void Create(wxWindow* parent,wxWindowID id,wxEvtHandler* evtHandler);
virtual wxGridCellEditor* Clone() const;
virtual void BeginEdit(int row, int col, wxGrid* grid);
virtual bool EndEdit(int row, int col, const wxGrid* grid,
const wxString& oldval, wxString *newval);
virtual void ApplyEdit(int row, int col, wxGrid* grid);
void SetById(wxString);
protected:
wxArrayString m_choices;
wxArrayString m_ids;
private:
wxString m_index;
wxDECLARE_NO_COPY_CLASS(DBGridCellChoiceEditor);
};
Code: Select all
mywidgets.cpp
DBComboBox::DBComboBox(wxWindow *parent, wxWindowID id, wxString defaultselection, const wxPoint pos, const wxSize size, int style) :
wxComboBox(parent,id,defaultselection,pos,size,0,NULL,style,wxDefaultValidator,wxEmptyString) { }
void DBComboBox::Prime(const wxArrayString *charray,wxArrayString *dataarray) {
Clear();
for (int i=0;i<charray->GetCount();++i) {
Append(charray->Item(i),new wxStringClientData(dataarray->Item(i)));
}
}
wxString DBComboBox::getid() {
int pos;
pos=GetSelection();
if (pos==wxNOT_FOUND) return "0";
return ((wxStringClientData*)GetClientObject(pos))->GetData();
}
// Selects the item in the listbox.
// Useful after the listbox has been primed.
void DBComboBox::setbyid(wxString id) {
unsigned int pos;
if (id.IsSameAs("0")) {
SetSelection(0);
return;
}
for (pos=0;pos<GetCount();++pos) {
if (id.IsSameAs(((wxStringClientData*)GetClientObject(pos))->GetData()))
SetSelection(pos);
}
}
DBGridCellChoiceEditor::DBGridCellChoiceEditor(const wxArrayString& choices,const wxArrayString &ids)
:wxGridCellChoiceEditor(),m_choices(choices),m_ids(ids)
{
m_index = "0";
}
wxGridCellEditor *DBGridCellChoiceEditor::Clone() const
{
DBGridCellChoiceEditor *editor = new DBGridCellChoiceEditor(m_choices,m_ids);
return editor;
}
void DBGridCellChoiceEditor::Create(wxWindow* parent,wxWindowID id,wxEvtHandler* evtHandler)
{
int style = wxTE_PROCESS_ENTER |
wxTE_PROCESS_TAB |
wxCB_READONLY |
wxBORDER_NONE;
int i;
m_control = new DBComboBox(parent, id, wxEmptyString,
wxDefaultPosition, wxDefaultSize,
style);
for (i=0;i<m_ids.size();++i)
((DBComboBox*)m_control)->Append(m_choices.Item(i),new wxStringClientData(m_ids.Item(i)));
wxGridCellEditor::Create(parent, id, evtHandler);
}
void DBGridCellChoiceEditor::BeginEdit(int row, int col, wxGrid* grid)
{
wxASSERT_MSG(m_control,
wxT("The DBGridCellChoiceEditor must be Created first!"));
wxGridCellEditorEvtHandler* evtHandler = NULL;
if (m_control)
evtHandler = wxDynamicCast(m_control->GetEventHandler(), wxGridCellEditorEvtHandler);
// Don't immediately end if we get a kill focus event within BeginEdit
if (evtHandler)
evtHandler->SetInSetFocus(true);
wxGridTableBase *table = grid->GetTable();
m_index=table->GetValue(row,col);
if (m_index.empty()) m_index="0";
SetById(m_index);
#ifdef __WXOSX_COCOA__
// This is a work around for the combobox being simply dismissed when a
// choice is made in it under OS X. The bug is almost certainly due to a
// problem in focus events generation logic but it's not obvious to fix and
// for now this at least allows to use wxGrid.
Combo()->Popup();
#endif
if (evtHandler)
{
// When dropping down the menu, a kill focus event
// happens after this point, so we can't reset the flag yet.
#if !defined(__WXGTK20__)
evtHandler->SetInSetFocus(false);
#endif
}
}
bool DBGridCellChoiceEditor::EndEdit(int WXUNUSED(row),
int WXUNUSED(col),
const wxGrid* WXUNUSED(grid),
const wxString& WXUNUSED(oldval),
wxString *newval)
{
wxString idx = ((DBComboBox*)m_control)->getid();
Show(true);
if ( idx.IsSameAs(m_index) )
return false;
m_index = idx;
if ( newval )
newval->Printf(m_index);
return true;
}
void DBGridCellChoiceEditor::ApplyEdit(int row, int col, wxGrid* grid)
{
wxGridTableBase * const table = grid->GetTable();
table->SetValue(row, col, m_index);
}
void DBGridCellChoiceEditor::SetById(wxString theid) {
((DBComboBox*)m_control)->setbyid(theid);
}