Populating wxDataViewListCtrl

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
Dadrick
In need of some credit
In need of some credit
Posts: 4
Joined: Fri Apr 23, 2021 9:48 pm

Populating wxDataViewListCtrl

Post by Dadrick »

Let me preface this question by saying I am a rank beginner in C++, wxWidgets, and VS2019.

I am trying to create a form that uses a wxTextCtrl to accept input from the user. After which the users clicks the enter button which sends the data to the wxDataViewListCtrl via the "m_dvlPairs->AppendItem(item);" command. The wxDataViewListBox receives and displays the new data as I expected. The trouble comes when a second entry is submitted in the same fashion - nothing happens. I tried using the InsertItem function and giving a 0 value for the row, but that just wipes the original data and replaces it with the new. What little nugget am I missing?

Code: Select all

void dvlcTest::OnPolyButtonClicked(wxCommandEvent& evt)
{
	wxString str = m_tbxPolyPt->GetValue();
	string newString = string(str.mb_str(wxConvUTF8));
	wxVector<wxVariant> item;
	item.push_back(wxVariant(newString));
	m_dvlPairs->AppendItem(item);
	m_tbxPolyPt->Clear();
	item.clear();
	evt.Skip();
}
Thanks, Dadrick.
User avatar
doublemax
Moderator
Moderator
Posts: 19114
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Populating wxDataViewListCtrl

Post by doublemax »

I can't spot any obvious mistake.

Does the column count always match the size of the vector?
What's with the unnecessary conversion from wxString to std::string and back?
Don't call evt.Skip()
Use the source, Luke!
Dadrick
In need of some credit
In need of some credit
Posts: 4
Joined: Fri Apr 23, 2021 9:48 pm

Re: Populating wxDataViewListCtrl

Post by Dadrick »

Does the column count always match the size of the vector?
Yes, that a simple one there is only a single text column.

Don't call evt.Skip()
User avatar
doublemax
Moderator
Moderator
Posts: 19114
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Populating wxDataViewListCtrl

Post by doublemax »

I suspect the error is not in this code, but somewhere else. Do you have any other event handlers? If it's not too much, can you show the complete code?
Use the source, Luke!
Dadrick
In need of some credit
In need of some credit
Posts: 4
Joined: Fri Apr 23, 2021 9:48 pm

Re: Populating wxDataViewListCtrl

Post by Dadrick »

Here you go,
The 4 files that are in my project.

dvlccTestApp.h

Code: Select all

#pragma once

#include "wx/wx.h"
#include "dvlcTest.h"

class dvlccTestApp : public wxApp
{
public:
	dvlccTestApp();
	~dvlccTestApp();

private:
	dvlcTest *m_frame1 = nullptr;

public:
	virtual bool OnInit();
};
dvlccTestApp.cpp

Code: Select all

#include "dvlccTestApp.h"

wxIMPLEMENT_APP(dvlccTestApp);

dvlccTestApp::dvlccTestApp()
{
}
dvlccTestApp::~dvlccTestApp()
{
}

bool dvlccTestApp::OnInit()
{
	m_frame1 = new dvlcTest();
	m_frame1->Show();
	return true;
}
dvlcTest.h

Code: Select all

#pragma once
#include "wx/wx.h"
#include "wx/dataview.h"

class dvlcTest : public wxFrame
{
public:
	dvlcTest();
	~dvlcTest();

public:
	wxTextCtrl* m_tbxPolyPt = nullptr; 
	wxButton* m_btnPolyIn = nullptr;
	wxDataViewListCtrl* m_dvlPairs = nullptr;

	void OnPolyButtonClicked(wxCommandEvent& evt);

	wxDECLARE_EVENT_TABLE();

};
and finally the dvlcTest.cpp

Code: Select all

#include "dvlcTest.h"
using namespace std;

// Start Event Handlers
wxBEGIN_EVENT_TABLE(dvlcTest, wxFrame)
	EVT_BUTTON(10001, OnPolyButtonClicked)
wxEND_EVENT_TABLE()

dvlcTest::dvlcTest() : wxFrame(nullptr,
	wxID_ANY,
	"Parcel Creator Entry",
	wxPoint(30, 30),
	wxSize(450, 800))
{
	m_tbxPolyPt = new wxTextCtrl(this,
		wxID_ANY,
		wxEmptyString,
		wxPoint(30, 180),
		wxSize(150, 30),
		wxTE_NOHIDESEL,
		wxDefaultValidator,
		wxT("tbxPoly"));

	m_btnPolyIn = new wxButton(this,
		10001,
		wxT("Enter Pair"),
		wxPoint(30, 240),
		wxSize(150, 30),
		wxBU_EXACTFIT,
		wxDefaultValidator,
		wxT("btnPolyIn"));

	m_dvlPairs = new wxDataViewListCtrl(this,
		wxID_ANY,
		wxPoint(30, 300),
		wxSize(150, 360),
		wxDV_HORIZ_RULES,
		wxDefaultValidator);
	m_dvlPairs->AppendTextColumn("Pairs");
}
dvlcTest::~dvlcTest()
{
}

void dvlcTest::OnPolyButtonClicked(wxCommandEvent& evt)
{
	wxString str = m_tbxPolyPt->GetValue();
	wxVector<wxVariant> item;
	item.push_back(wxVariant(str));
	m_dvlPairs->AppendItem(item);
	m_tbxPolyPt->Clear();
	item.clear();
}
I understand that they can probably be combined into just two files. Again I'm a real newbie and was following/expanding on an example.
User avatar
doublemax
Moderator
Moderator
Posts: 19114
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Populating wxDataViewListCtrl

Post by doublemax »

It seems that wxDataViewListCtrl doesn't like to have a fixed size and not being inside a sizer. By adding m_dvlPairs->Layout(); after m_dvlPairs->AppendItem(item); the items started appearing. So it was more or less only a visual issue.

But you should avoid using absolute positions and sizes anyway and use sizers instead:

Code: Select all

#include "dvlcTest.h"
using namespace std;

// Start Event Handlers
wxBEGIN_EVENT_TABLE(dvlcTest, wxFrame)
  EVT_BUTTON(10001, OnPolyButtonClicked)
wxEND_EVENT_TABLE()

dvlcTest::dvlcTest() : wxFrame(nullptr,
  wxID_ANY,
  "Parcel Creator Entry",
  wxPoint(30, 30),
  wxSize(450, 800))
{
  wxPanel *panel = new wxPanel(this, wxID_ANY);
  wxBoxSizer *mainSizer = new wxBoxSizer(wxVERTICAL);

  m_tbxPolyPt = new wxTextCtrl(panel, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxTE_NOHIDESEL);
  mainSizer->Add( m_tbxPolyPt, 0, wxEXPAND|wxALL, 4);

  m_btnPolyIn = new wxButton(panel, 10001, wxT("Enter Pair"), wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT);
  mainSizer->Add( m_btnPolyIn, 0, wxEXPAND|wxALL, 4);

  m_dvlPairs = new wxDataViewListCtrl(panel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxDV_HORIZ_RULES);
  m_dvlPairs->AppendTextColumn("Pairs", wxDATAVIEW_CELL_INERT, -1);
  mainSizer->Add( m_dvlPairs, 1, wxEXPAND|wxALL, 4);

  panel->SetSizer(mainSizer);

}
dvlcTest::~dvlcTest()
{
}

void dvlcTest::OnPolyButtonClicked(wxCommandEvent& evt)
{
  wxString str = m_tbxPolyPt->GetValue();
  if( str.IsEmpty() ) return;

  wxVector<wxVariant> item;
  item.push_back(wxVariant(str));
  m_dvlPairs->AppendItem(item);
  m_tbxPolyPt->Clear();
}
Sizers are often a little confusing for wxWidgets beginners, but they will make your live much easier.
http://neume.sourceforge.net/sizerdemo/
Use the source, Luke!
Dadrick
In need of some credit
In need of some credit
Posts: 4
Joined: Fri Apr 23, 2021 9:48 pm

Re: Populating wxDataViewListCtrl

Post by Dadrick »

Thank you so much. =D> =D>

I would have never thought it would be solved using a sizer. But it does!!

I will incorporate this knowledge into the main code. The are several more controls that need to be added. I will study up on sizers and make it work.
Post Reply