OVERVIEW
In the sample code below, we setup two wxListCtrl widgets. One of them is filled with string items. The other is empty. We can drag items from the first one to the other to populate the second list. In this case we are using wxTextDropTarget
SAMPLE CODE
dragdrop.h
#include <wx/wxprec.h>
#ifndef WX_PRECOMP
#include <wx/wx.h>
#endif
#include <wx/dnd.h>
#include <wx/listctrl.h>
class DragDrop: public wxFrame {
public:
DragDrop(const wxString& title);
void onDragInit(wxListEvent& event);
private:
wxListCtrl *mList1, *mList2;
};
class DropTarget:public wxTextDropTarget {
public:
DropTarget(wxListCtrl *owner);
virtual bool OnDropText(wxCoord x, wxCoord y, const wxString& data);
private:
wxListCtrl *mOwner;
};
dragdrop.cpp
#include "dragdrop.h"
DragDrop::DragDrop(const wxString& title):
wxFrame(NULL, -1, title, wxDefaultPosition, wxSize(500,200)) {
wxPanel *panel = new wxPanel(this,-1);
wxBoxSizer *hbox = new wxBoxSizer(wxHORIZONTAL);
panel->SetSizer(hbox);
mList1 = new wxListCtrl(panel, -1, wxDefaultPosition, wxDefaultSize, wxLC_LIST | wxLC_SINGLE_SEL);
mList2 = new wxListCtrl(panel, -1, wxDefaultPosition, wxDefaultSize, wxLC_LIST);
hbox->Add(mList1, 1, wxALL | wxEXPAND, 10);
hbox->Add(mList2, 1, wxALL | wxEXPAND,10);
DropTarget *drop = new DropTarget(mList2);
mList2->SetDropTarget(drop);
wxString value = wxT("");
for(int i=1; i <= 50; i++) {
value = "Item ";
value.Append(wxString::Format(wxT("%d"),i));
mList1->InsertItem(i, value);
}
Connect(mList1->GetId(), wxEVT_LIST_BEGIN_DRAG,
wxListEventHandler(DragDrop::onDragInit));
Center();
}
void DragDrop::onDragInit(wxListEvent& event) {
long sel = mList1->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
if (sel > -1) {
wxString text = mList1->GetItemText(sel,0);
wxTextDataObject tdo(text);
wxDropSource tds(tdo, mList1);
tds.DoDragDrop(wxDrag_CopyOnly);
}
}
DropTarget::DropTarget(wxListCtrl *owner) {
mOwner = owner;
}
bool DropTarget::OnDropText(wxCoord x, wxCoord y, const wxString& data) {
int count = mOwner->GetItemCount();
mOwner->InsertItem(count, data);
return true;
}
main.h
#include <wx/wxprec.h>
#ifndef WX_PRECOMP
#include <wx/wx.h>
#endif
class Main: public wxApp {
public:
virtual bool OnInit();
};
main.cpp
#include "main.h"
#include "dragdrop.h"
IMPLEMENT_APP(Main)
bool Main::OnInit() {
DragDrop *app = new DragDrop(wxT("Drag And Drop"));
app->Show(true);
}
The output is shown below
I was surprised you used Connect in dragdrop.cpp, line 27. Earlier in the sequence of your code, you stated that you would only use Bind. The following replacement for the Connect code worked for me:
mList1->Bind(wxEVT_LIST_BEGIN_DRAG, &TextDragFrame::onDragInit, this);
Be well!
Greg.
Thanks for noticing that, Greg. Yes I should have used Bind. Appreciate your fix.