Search code examples
c++wxwidgets

How to store Key / Value Pair wxDataViewListCtrl without using wxDataViewModel


I have below sample data available in database


SrNo | String

1 | Data1

2 | Data2

3 | Data3

4 | Data2

5 | Data1

String column value can be duplicate. User can also filter data displayed in wxDataViewListCtrl using wxSearchCtrl, so ID number displayed inside wxDataViewListCtrl might change based on filter used by user.

https://docs.wxwidgets.org/3.0/classwx_data_view_list_ctrl.html

Using example shown above link, inserting data from database into listctrl with a while loop. sample code is below.

wxDataViewListCtrl *listctrl = new wxDataViewListCtrl( parent, wxID_ANY );
listctrl->AppendTextColumn( "String Data" );
wxVector<wxVariant> data;
data.push_back( wxVariant("Data1") );
listctrl->AppendItem( data );
data.clear();
data.push_back( wxVariant("Data2") );
listctrl->AppendItem( data );

How to get SrNo of Selected row? in below code? Do I need to use wxDataViewModel? I didn't find any examples for the same

if(listctrl->GetSelectedRow() != wxNOT_FOUND){
        wxLogMessage("Select Item Id: %i -",listctrl->RowToItem(listctrl->GetSelectedRow()).GetID() );
    }else{
        wxMessageBox("Please Select row", strappName,wxICON_INFORMATION|wxCLOSE); 
    }

Tried below sample code but it crashes with segmentation fault. Looking for sample code

listctrl->SetItemData(wxDataViewItem (reinterpret_cast<void *>(iRowCount)),std::stoi(SrNo))

Solution

  • Use the "wxUIntPtr" parameter in AppendItem/InsertItem etc... to store your internal index.

    wxVector<wxVariant> data;
    data.push_back( wxVariant("Data1") );
    listctrl->AppendItem( data, wxUIntPtr(1) );  // <<HERE, your index 1>>
    data.clear();
    data.push_back( wxVariant("Data2") );
    listctrl->AppendItem( data, wxUIntPtr(2) );  // <<and HERE, your index 2>>
    

    Then use RowToItem(int row) to get a wxDataViewItem for your row and use GetItemData to get the wxUIntPtr and convert that back to your id. For example

    // Get the wxDataViewItem for "GetSelectedRow" (Warning, not tested for wxID_NOTFOUND)
    auto idx=listctrl->RowToItem(GetSelectedRow());
    
    // Now get the item data, which was added as 2nd parameter for Append/InsertItem
    auto your_index_asUIntPtr=listctrl->GetItemData(idx);
    
    // and in your case convert it back to an int
    int your_index_as_it=(int)your_index_asUIntPtr;
    

    That should to the trick.

    In general, most wxWidgets list functions have an additional void* or wxUIntPtr that you can use to add your own data to a specific entry in the list. You have to either cast this parameter to your own primitive datatype (int, long etc...). Or you can use this pointer to point to an actual complex data type (pointer casts are needed still), but the list controls will never take ownership of the pointer.

    So something like this listctrl->InsertItem(something, (wxUIntPtr)new std::string("Hey, additional string") will result in a memory leak.