If wxDataViewCtrl has a huge number of data, the control cannot be updated if displayed rows are beyond a specific limit. Compile the followings by supplying appropriate lib files. If the topmost row is less than 6100806 everything is OK. Otherwise updating the control stops, that you can easily confirm by enlarging the window. I googled to find probably the same issue repored (https://groups.google.com/g/wx-users/c/XEjLpl1wTRc), which doesn't show the solution however.
Code: Select all
#include <wx/wx.h>
#include <wx/dataview.h>
class MyModel:public wxDataViewVirtualListModel
{
public:
unsigned int GetColumnCount() const override {return 1;}
wxString GetColumnType(unsigned int col) const override {return "string";}
void GetValueByRow
(wxVariant& variant,unsigned int row,unsigned int col) const override
{variant=wxString::Format("%d",row);}
bool SetValueByRow
(const wxVariant& variant,unsigned int row,unsigned int col) override
{return false;}
};
class MyFrame:public wxFrame
{
public:
MyFrame(wxWindow* parent,wxWindowID id):wxFrame{parent,id,"DataViewCtrlTest"}
{
auto* ctrl=new wxDataViewCtrl{this,wxID_ANY};
auto* model=new MyModel{};
ctrl->AppendTextColumn("Row",0);
ctrl->AssociateModel(model);
model->DecRef();
model->Reset(97612892);
ctrl->EnsureVisible(model->GetItem(6100806));
}
};
class MyApp:public wxApp
{
public:
bool OnInit() override
{
auto* frame=new MyFrame{nullptr,wxID_ANY};
frame->Show();
SetTopWindow(frame);
return true;
}
};
wxIMPLEMENT_APP(MyApp);
All drawing operations on the wxBufferedPaintDC are actually on the wxBufferedDC, before the wxBufferPaintedDC destructor (include/wx/dcbuffer.h:183) calls wxBufferedDC::UnMask() (src/common/dcbufcmn.cpp:134) to copy (BitBlt) the contents to the actual DC. If the top-left logical coordinates of the wxBufferedDC are beyond the "device cordinate space" the BitBlt fails. If the topmost row is 6100806 the top y-cordinate is 6100806*22(line height) = 2^27+4 > 2^27, which is beyond the space.
To solve the issue in a project targetting only MSW I avoided calling the wxScrollHelper::PrepareDC() in wxDataViewMainWindow::OnPaint() and changed all drawing operations on the DC from by unscrolled coordinates to by scrolled coordinates. The patch has worked well so far.
I'm not completely sure what I have guessed is right. Is there something I overlooked? Thank you.