wxTreeListCtrl not sorting (Issue #22852)

60 views
Skip to first unread message

FillipMatthew

unread,
Oct 6, 2022, 11:06:23 AM10/6/22
to wx-...@googlegroups.com, Subscribed

Description

The wxTreeListCtrl does not obey SetSortColumn(). Calling SetSortColumn only changes the indicators on the column, it does not actually sort. Also After calling SetSortColumn() clicking on the columns to sort sometimes works and sometimes does not.

#include <wx/wx.h>
#include <wx/treelist.h>

class CTestFrameDlg : public wxFrame
{
public:
	CTestFrameDlg(wxWindow * parent, wxWindowID id = wxID_ANY, const wxString & title = wxT("Test Frame"), const wxPoint & pos = wxDefaultPosition,
	    const wxSize & size = wxSize(640, 480), long style = wxDEFAULT_FRAME_STYLE | wxRESIZE_BORDER | wxTAB_TRAVERSAL)
	    : wxFrame(parent, id, title, pos, size, style)
	{
		this->SetSizeHints(wxDefaultSize, wxDefaultSize);

		wxBoxSizer * bSizer2;
		bSizer2 = new wxBoxSizer(wxVERTICAL);

		m_treeListCtrl1 = new wxTreeListCtrl(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTL_DEFAULT_STYLE | wxTL_SINGLE);

		bSizer2->Add(m_treeListCtrl1, 1, wxEXPAND | wxALL, 3);

		wxBoxSizer * bSizer21;
		bSizer21 = new wxBoxSizer(wxHORIZONTAL);

		m_button1 = new wxButton(this, wxID_ANY, wxT("Column 1"), wxDefaultPosition, wxDefaultSize, 0);
		bSizer21->Add(m_button1, 0, wxALL, 3);

		m_button2 = new wxButton(this, wxID_ANY, wxT("Column 2"), wxDefaultPosition, wxDefaultSize, 0);
		bSizer21->Add(m_button2, 0, wxALL, 3);

		m_button3 = new wxButton(this, wxID_ANY, wxT("Column 3"), wxDefaultPosition, wxDefaultSize, 0);
		bSizer21->Add(m_button3, 0, wxALL, 3);

		bSizer2->Add(bSizer21, 0, 0, 3);

		this->SetSizer(bSizer2);
		this->Layout();

		this->Centre(wxBOTH);

		// Connect Events
		this->Connect(wxEVT_CLOSE_WINDOW, wxCloseEventHandler(CTestFrameDlg::OnClose));
		m_button1->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CTestFrameDlg::OnButton1), NULL, this);
		m_button2->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CTestFrameDlg::OnButton2), NULL, this);
		m_button3->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CTestFrameDlg::OnButton3), NULL, this);

		Init();
	}

	~CTestFrameDlg()
	{
		// Disconnect Events
		this->Disconnect(wxEVT_CLOSE_WINDOW, wxCloseEventHandler(CTestFrameDlg::OnClose));
		m_button1->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CTestFrameDlg::OnButton1), NULL, this);
		m_button2->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CTestFrameDlg::OnButton2), NULL, this);
		m_button3->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CTestFrameDlg::OnButton3), NULL, this);
	}

protected:
	void Init()
	{
		m_treeListCtrl1->AppendColumn("Index", 120, wxALIGN_LEFT, wxCOL_RESIZABLE | wxCOL_SORTABLE);
		m_treeListCtrl1->AppendColumn("Column 1", 120, wxALIGN_LEFT, wxCOL_RESIZABLE | wxCOL_SORTABLE);
		m_treeListCtrl1->AppendColumn("Column 2", 120, wxALIGN_LEFT, wxCOL_RESIZABLE | wxCOL_SORTABLE);
		m_treeListCtrl1->AppendColumn("Column 3", 120, wxALIGN_LEFT, wxCOL_RESIZABLE | wxCOL_SORTABLE);
		m_treeListCtrl1->AppendColumn("Column 4", 120, wxALIGN_LEFT, wxCOL_RESIZABLE | wxCOL_SORTABLE);
		m_treeListCtrl1->AppendColumn("Column 5", 120, wxALIGN_LEFT, wxCOL_RESIZABLE | wxCOL_SORTABLE);

		wxTreeListItem id = m_treeListCtrl1->AppendItem(m_treeListCtrl1->GetRootItem(), "1");
		m_treeListCtrl1->SetItemText(id, 1, "A");
		m_treeListCtrl1->SetItemText(id, 2, "B");
		m_treeListCtrl1->SetItemText(id, 3, "C");
		m_treeListCtrl1->SetItemText(id, 4, "D");
		m_treeListCtrl1->SetItemText(id, 5, "E");

		id = m_treeListCtrl1->AppendItem(m_treeListCtrl1->GetRootItem(), "2");
		m_treeListCtrl1->SetItemText(id, 1, "B");
		m_treeListCtrl1->SetItemText(id, 2, "C");
		m_treeListCtrl1->SetItemText(id, 3, "D");
		m_treeListCtrl1->SetItemText(id, 4, "E");
		m_treeListCtrl1->SetItemText(id, 5, "A");

		id = m_treeListCtrl1->AppendItem(m_treeListCtrl1->GetRootItem(), "3");
		m_treeListCtrl1->SetItemText(id, 1, "C");
		m_treeListCtrl1->SetItemText(id, 2, "D");
		m_treeListCtrl1->SetItemText(id, 3, "E");
		m_treeListCtrl1->SetItemText(id, 4, "A");
		m_treeListCtrl1->SetItemText(id, 5, "B");

		id = m_treeListCtrl1->AppendItem(m_treeListCtrl1->GetRootItem(), "4");
		m_treeListCtrl1->SetItemText(id, 1, "D");
		m_treeListCtrl1->SetItemText(id, 2, "E");
		m_treeListCtrl1->SetItemText(id, 3, "A");
		m_treeListCtrl1->SetItemText(id, 4, "B");
		m_treeListCtrl1->SetItemText(id, 5, "C");

		id = m_treeListCtrl1->AppendItem(m_treeListCtrl1->GetRootItem(), "5");
		m_treeListCtrl1->SetItemText(id, 1, "E");
		m_treeListCtrl1->SetItemText(id, 2, "A");
		m_treeListCtrl1->SetItemText(id, 3, "B");
		m_treeListCtrl1->SetItemText(id, 4, "C");
		m_treeListCtrl1->SetItemText(id, 5, "D");
	}

	void OnClose(wxCloseEvent & event)
	{
		Destroy();
	}
	void OnButton1(wxCommandEvent & event)
	{
		m_treeListCtrl1->SetSortColumn(1, true);
	}
	void OnButton2(wxCommandEvent & event)
	{
		m_treeListCtrl1->SetSortColumn(2, true);
	}
	void OnButton3(wxCommandEvent & event)
	{
		m_treeListCtrl1->SetSortColumn(3, true);
	}

private:
	wxTreeListCtrl * m_treeListCtrl1;
	wxButton * m_button1;
	wxButton * m_button2;
	wxButton * m_button3;
};

class MyApp : public wxApp
{
public:
	bool OnInit()  // wxOVERRIDE
	{
		if (!wxApp::OnInit())
			return false;

		CTestFrameDlg * frame = new CTestFrameDlg(nullptr);
		wxTheApp->SetTopWindow(frame);
		frame->Show(true);
		return true;
	}
};

IMPLEMENT_APP(MyApp);

To Reproduce:
Click on any of the column buttons bellow the control.

Platform and version information

  • wxWidgets version you use: 3.2.1
  • wxWidgets port you use: wxMSW
  • OS and its version: Windows 10


Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/issues/22852@github.com>

David Connet

unread,
Oct 6, 2022, 11:15:26 AM10/6/22
to wx-...@googlegroups.com, Subscribed

It's not supposed to. You need to connect to the column click event, do your sorting (because how you sort is completely dependent on your data), and then set the sort indicator from that.


Reply to this email directly, view it on GitHub, or unsubscribe.

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/issues/22852/1270245367@github.com>

PB

unread,
Oct 6, 2022, 1:55:25 PM10/6/22
to wx-...@googlegroups.com, Subscribed

If calling wxTreeListCtrl::SetSortColumn() does not sort the list, its documentation should be changed as it now contains

Calling this method resorts the control contents using the values of the items in the specified column.

The docs also has

Notice that currently there is no way to reset sort order.

which IMO makes the method rather impractical.


Reply to this email directly, view it on GitHub, or unsubscribe.

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/issues/22852/1270472156@github.com>

David Connet

unread,
Oct 6, 2022, 2:05:09 PM10/6/22
to wx-...@googlegroups.com, Subscribed

Oops, sorry - I missed this was against wxTreeListCtrl (I don't use that). I was thinking of wxListCtrl.


Reply to this email directly, view it on GitHub, or unsubscribe.

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/issues/22852/1270483014@github.com>

VZ

unread,
Oct 6, 2022, 5:59:25 PM10/6/22
to wx-...@googlegroups.com, Subscribed

This should indeed work and I don't see why it doesn't at a glance, this needs to be debugged...


Reply to this email directly, view it on GitHub, or unsubscribe.

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/issues/22852/1270736998@github.com>

PB

unread,
Oct 7, 2022, 6:47:08 AM10/7/22
to wx-...@googlegroups.com, Subscribed

This should indeed work and I don't see why it doesn't at a glance, this needs to be debugged...

I am not familiar with wxDVC so I am probably missing something, but FWIW I have traced the code

wxTreeListCtrl::SetSortColumn()
  wxDataViewColumn::SetSortOrder()
    wxDataViewCtrl::OnColumnChange()
      wxDataViewMainWindow::UpdateDisplay()

and could not see any place where sorting the control is done or triggered (i.e., something like the code in wxDataViewHeaderWindow::OnClick(), calling wxDataViewModel::Resort()).

I can make the sorting "work" if after calling SetSortColumn() call GetDataView()->GetModel()->Resort(). Of course, it still only works once due to the SetSortColumn() limitation listed in the docs I mentioned in my previous post.


Reply to this email directly, view it on GitHub, or unsubscribe.

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/issues/22852/1271430441@github.com>

VZ

unread,
Oct 8, 2022, 7:32:01 PM10/8/22
to wx-...@googlegroups.com, Subscribed

If calling Resort() is enough, maybe we just need to document that it must be done? Of course, it would be better if you didn't have to do it, but I'm not sure about the details of sorting in the native versions to be sure that we can avoid it.

OTOH I think the presence of ResetAllSortColumns() only in the generic version is due to the fact that only it supports sorting by multiple columns anyhow, i.e. I don't think GTK does (but not sure about Mac).


Reply to this email directly, view it on GitHub, or unsubscribe.

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/issues/22852/1272413227@github.com>

VZ

unread,
Dec 17, 2022, 9:01:29 PM12/17/22
to wx-...@googlegroups.com, Subscribed

I think I've fixed it in the PR above, at least the original example now works fine for me under both MSW (using the generic version) and GTK (using the native one).

As usual with wxDVC, I'm not sure what the design was/is, e.g. maybe it should actually resort itself automatically when wxDataViewColumn::SetSortOrder() is called, but for now we can at least fix the problem at wxTreeListCtrl level (which still required fixing other things in wxDVC).

Please test the PR and let me know if you see any problems with it, TIA!


Reply to this email directly, view it on GitHub, or unsubscribe.

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/issues/22852/1356625689@github.com>

VZ

unread,
Dec 23, 2022, 2:14:33 PM12/23/22
to wx-...@googlegroups.com, Subscribed

Closed #22852 as completed via 4d33ddc.


Reply to this email directly, view it on GitHub, or unsubscribe.

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/issue/22852/issue_event/8105465512@github.com>

Reply all
Reply to author
Forward
0 new messages