Hi everybody!
Is there a way to make a wxListCtrl sortable only if the user clicks on the header? I 've already tried with the style wxLC_SORT but it does not do what I want it to do..
Example: I have a wxListCtrl in report mode where in each line I have 3 cols: name, surname, age and I wait to sort the table looking at the Surname..
Thanks very much!
WxListCtrl sortable
Re: WxListCtrl sortable
Hi,
Thank you.
Does it sort the data if you click anywhere else?wxJack wrote: Hi everybody!
Is there a way to make a wxListCtrl sortable only if the user clicks on the header?
Thank you.
Re: WxListCtrl sortable
For now no, it doesn't ..
I can do a button doing this but I was wondering if there is an easier way to do it:)
I can do a button doing this but I was wondering if there is an easier way to do it:)
Re: WxListCtrl sortable
Hi,
I don't think the control implements sorting.
You can catch the click on the column header, clean the control, resort the data and then re-append the data back.
Thank you.
I don't think the control implements sorting.
You can catch the click on the column header, clean the control, resort the data and then re-append the data back.
Thank you.
Re: WxListCtrl sortable
The following example shows a simples way how to sort the list when clicking on a column. Please notice it has major flaws, such as there is no indicator showing by which column is the list sorted (I believe that listctrl sample shows how to add an image to the column header). The code could be also simplifed by having a sort column index stored in the data so that only one compare function would be necessary...
I would also prefer using virtual list ctrl and doing the sorting in the data (e.g. the std::vector in the code below) themselves.
You may be better off using wxDataView(List)Ctrl instead of wxListCtrl...
I would also prefer using virtual list ctrl and doing the sorting in the data (e.g. the std::vector in the code below) themselves.
Code: Select all
#include <wx/wx.h>
#include <wx/listctrl.h>
#include <vector>
struct Country
{
wxString name;
wxString capital;
wxString continent;
};
typedef std::vector<Country> CountryList;
class MyListCtrl : public wxListCtrl
{
public:
MyListCtrl(wxWindow* parent) : wxListCtrl(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_REPORT)
{
Country c;
c.name = "Canada"; c.capital = "Ottawa"; c.continent = "America";
m_countries.push_back(c);
c.name = "Germany"; c.capital = "Berlin"; c.continent = "Europe";
m_countries.push_back(c);
c.name = "Japan"; c.capital = "Tokyo"; c.continent = "Asia";
m_countries.push_back(c);
InsertColumn(Column_Name, _("Name"));
InsertColumn(Column_Capital, _("Capital"));
InsertColumn(Column_Continent, _("Continent"));
for ( size_t i = 0; i < m_countries.size(); ++i )
{
const Country& country = m_countries[i];
long result = InsertItem(i, country.name);
SetItem(result, Column_Capital, country.capital);
SetItem(result, Column_Continent, country.continent);
SetItemData(result, (long)i);
}
Bind(wxEVT_LIST_COL_CLICK, &MyListCtrl::OnColClick, this);
}
private:
enum Columns
{
Column_Name = 0,
Column_Capital,
Column_Continent
};
CountryList m_countries;
void OnColClick(wxListEvent& evt)
{
int column = evt.GetColumn();
if ( column < 0 )
return;
if ( column == Column_Name )
SortItems(CompareName, reinterpret_cast<wxIntPtr>(&m_countries));
else
if ( column == Column_Capital )
SortItems(CompareCapital, reinterpret_cast<wxIntPtr>(&m_countries));
else
if ( column == Column_Continent)
SortItems(CompareContinent, reinterpret_cast<wxIntPtr>(&m_countries));
else
wxFAIL;
}
static void GetCountries(wxIntPtr item1, wxIntPtr item2, wxIntPtr sortData,
Country& c1, Country& c2)
{
CountryList* countries = reinterpret_cast<CountryList*>(sortData);
c1 = (*countries)[static_cast<size_t>(item1)];
c2 = (*countries)[static_cast<size_t>(item2)];
}
static int wxCALLBACK CompareName(wxIntPtr item1, wxIntPtr item2, wxIntPtr sortData)
{
Country c1, c2;
GetCountries(item1, item2, sortData, c1, c2);
return c1.name.CmpNoCase(c2.name);
}
static int wxCALLBACK CompareCapital(wxIntPtr item1, wxIntPtr item2, wxIntPtr sortData)
{
Country c1, c2;
GetCountries(item1, item2, sortData, c1, c2);
return c1.capital.CmpNoCase(c2.capital);
}
static int wxCALLBACK CompareContinent(wxIntPtr item1, wxIntPtr item2, wxIntPtr sortData)
{
Country c1, c2;
GetCountries(item1, item2, sortData, c1, c2);
return c1.continent.CmpNoCase(c2.continent);
}
};
class MyApp : public wxApp
{
public:
bool OnInit()
{
wxFrame* frame = new wxFrame(NULL, wxID_ANY, "Test", wxDefaultPosition, wxSize(600, 400));
new MyListCtrl(frame);
frame->Show();
return true;
}
}; wxIMPLEMENT_APP(MyApp);
Re: WxListCtrl sortable
many thanks to both of you guys, very appreciated your help )