Displaying deleted rows in wxListCtrl

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
Post Reply
CnnC
Earned a small fee
Earned a small fee
Posts: 24
Joined: Thu Mar 08, 2018 7:40 am

Displaying deleted rows in wxListCtrl

Post by CnnC » Tue Mar 24, 2020 6:56 am

Good day!

When deleting items, wxListCtrl objects residual information about items that have already been deleted. It is displayed as rows that cannot be selected. This is usually the last row or group of rows when deleting several selected rows. These rows can't be selected, but they are present. How to set up the correct display of the remaining rows?

Code: Select all

Bind(wxEVT_TOOL, [=](wxCommandEvent) {
	wxArrayInt arrInt;
	long itemIndex = -1;
	while ((itemIndex = lcCalcTbl->GetNextItem(itemIndex,
	wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED)) != wxNOT_FOUND) {
		arrInt.Add(itemIndex);
	} 
	for ( long n = ( arrInt.GetCount() -1 ); 0 <= n; n-- ) {
		lcCalcTbl->DeleteItem( arrInt[ n ] );
	}
}, XRCID("tbiDelRow"));

Kvaz1r
I live to help wx-kind
I live to help wx-kind
Posts: 183
Joined: Tue Jun 07, 2016 1:07 pm

Re: Displaying deleted rows in wxListCtrl

Post by Kvaz1r » Tue Mar 24, 2020 8:39 am

DeleteItem is indeed delete item, you can check it in listctrl sample. Can you provide reproducible code?

CnnC
Earned a small fee
Earned a small fee
Posts: 24
Joined: Thu Mar 08, 2018 7:40 am

Re: Displaying deleted rows in wxListCtrl

Post by CnnC » Tue Mar 24, 2020 9:03 am

Yes, the elements were removed. But there is a "residual" display of them. Something in the form of their "footprints". Everything is fine when I minimize and expand the window.

Kvaz1r
I live to help wx-kind
I live to help wx-kind
Posts: 183
Joined: Tue Jun 07, 2016 1:07 pm

Re: Displaying deleted rows in wxListCtrl

Post by Kvaz1r » Tue Mar 24, 2020 9:25 am

Something in layouting. Check does the behaviour exist in listctrl sample. If no - it's mistake in your code (maybe some problem with sizers or something), if yes - it's probably bug.

CnnC
Earned a small fee
Earned a small fee
Posts: 24
Joined: Thu Mar 08, 2018 7:40 am

Re: Displaying deleted rows in wxListCtrl

Post by CnnC » Tue Mar 24, 2020 9:27 am

Found a way out:
1. clear the background of the list table;
2. refresh all items.

Now items are displayed correctly after deleting some of them.

Code: Select all

Bind(wxEVT_TOOL, [=](wxCommandEvent) {
            
            wxArrayInt arrInt;
            long itemIndex = -1;
            
            while ( ( itemIndex = lcCalcTbl->GetNextItem( itemIndex,
                wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED ) ) != wxNOT_FOUND) {
                arrInt.Add(itemIndex);
            }
            
            for ( long n = ( arrInt.GetCount() -1 ); 0 <= n; n-- ) {
                lcCalcTbl->DeleteItem( arrInt[ n ] );
                lcCalcTbl->ClearBackground();
            }
            
            lcCalcTbl->ClearBackground();
            
            for ( long i = 0; i < lcCalcTbl->GetItemCount(); ++i ) {
                lcCalcTbl->RefreshItem(i);
            }

        }, XRCID("tbiDelRow"));

User avatar
doublemax
Moderator
Moderator
Posts: 14613
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Displaying deleted rows in wxListCtrl

Post by doublemax » Tue Mar 24, 2020 11:10 am

Just calling lcCalcTbl->Refresh() at the end should be enough.
Use the source, Luke!

CnnC
Earned a small fee
Earned a small fee
Posts: 24
Joined: Thu Mar 08, 2018 7:40 am

Re: Displaying deleted rows in wxListCtrl

Post by CnnC » Tue Mar 24, 2020 12:56 pm

Thanks. This also works, but before that you need to clean the background.

PB
Part Of The Furniture
Part Of The Furniture
Posts: 2230
Joined: Sun Jan 03, 2010 5:45 pm

Re: Displaying deleted rows in wxListCtrl

Post by PB » Tue Mar 24, 2020 3:55 pm

calling just Refresh() clears the background, see its parameters: I do not remember ever having to clear background when deleting list control items, but I am on Windows only...

FWIW, I could not reproduce the issue with this code (but perhaps it depends on list control style?)

Code: Select all

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

#include <vector>

class MyDialog : public wxDialog
{
public:
    MyDialog() : wxDialog(nullptr, wxID_ANY, "Test")
    {                               
        wxBoxSizer* mainSizer = new wxBoxSizer(wxVERTICAL);        

        m_listView = new wxListView(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_LIST);        
        for ( int i = 0; i < 50; ++i )
            m_listView->InsertItem(m_listView->GetItemCount(), wxString::Format("Item %d", i));                    
        mainSizer->Add(m_listView, wxSizerFlags().Expand().Proportion(1).Border());

        wxButton* button = new wxButton(this, wxID_ANY, "Delete selected items");
        button->Bind(wxEVT_BUTTON, &MyDialog::OnDeleteSelectedItems, this);
        mainSizer->Add(button, wxSizerFlags().Expand().Border());        
                            
        SetSizer(mainSizer);         
    }	
private:
    wxListView* m_listView;

    void OnDeleteSelectedItems(wxCommandEvent&)
    {        
        std::vector<long> selected;
	    
        for ( long itemIndex = m_listView->GetFirstSelected();
              itemIndex != wxNOT_FOUND;
              itemIndex = m_listView->GetNextSelected(itemIndex) )
        {
            selected.push_back(itemIndex);
        }

        for ( auto it = selected.rbegin(); it != selected.rend(); ++it )
            m_listView->DeleteItem(*it);
        
        m_listView->Refresh();        
    }
};

class MyApp : public wxApp
{
public:	
    bool OnInit() override
    {
        MyDialog().ShowModal();
        return false;
    }
}; wxIMPLEMENT_APP(MyApp);

Post Reply