RE: wxDataViewCtrl problems (with full example) -- please help

819 views
Skip to first unread message

Petr Prikryl

unread,
Nov 15, 2007, 6:36:13 AM11/15/07
to wx-u...@lists.wxwidgets.org
Robert Roebling wrote:
> Petr Prikryl wrote:
>
> > As more people suggested me to use wxDataViewCtrl instead of
> > wxListView, I tried to prepare as simple as possible example
> > (see below). When using some extremely big number of lines,
> > I have observed some problems. When sliding the right scroll
> > bar, the last displayed line differs from time to time. I have
> > never displayed the last wanted line.
>
> Thanks for trying wxDataViewCtrl. The code in wxWidgets 2.8.6
> has almost nothing in common with the code in SVN TRUNK and
> [...]

(By the way, is this the correct mailing list to ask this question?)

Summary: The new attempt compiles but no data is displayed. See the
steps and the code below.

Details
=======

O.K. I have got revision 49964 and tried to compile the Unicode Debug
libraries on Windows, Visual Studio 2005. I have got some errors that
were apparently caused by missing wxWidgets/include/wx/msw/setup.h.
So, I manually copied my wxWidgets/include/wx/msw/setup0.h into setup.h
and compiled the libraries.

After that I have updated my sample to the form below and compiled
also Unicode Debug variant. It compiles with 15 warnings

------ Rebuild All started: Project: DataViewSample, Configuration:
Unicode Debug Win32 ------
Deleting intermediate and output files for project 'DataViewSample',
configuration 'Unicode Debug|Win32'
Compiling...
DataViewSample.cpp
c:\wxwidgets\include\wx\wxcrt.h(456) : warning C4267: 'return' :
conversion from 'size_t' to 'int', possible loss of data
c:\wxwidgets\include\wx\wxcrt.h(464) : warning C4267: 'return' :
conversion from 'size_t' to 'int', possible loss of data
c:\wxwidgets\include\wx\wxcrt.h(454) : warning C4267: 'return' :
conversion from 'size_t' to 'int', possible loss of data
c:\wxwidgets\include\wx\wxcrt.h(456) : see reference to function
template instantiation 'int wxStrspn_String<const wchar_t*>(const
wxString &,const T &)' being compiled
with
[
T=const wchar_t *
]

.... and instantiations for other types (left out for brevity)


When running the code, The window appears, the column headings
are displayed, but no lines are displayed. The
MyDataViewModel::GetValue()
is not called at all. Where is the error hidden in my code?

Thanks,
pepr

======================================================
#include "wx/wx.h"
#include "wx/dataview.h"

// Generated data for the DataView.
class MyDataViewModel: public wxDataViewIndexListModel
{
public:
virtual unsigned int GetColumnCount() const { return 50; }
virtual unsigned int GetRowCount() { return 10000; }
virtual wxString GetColumnType(unsigned int col) const { return
wxT("string"); }

virtual void GetValue(wxVariant &variant, unsigned int row, unsigned
int col) const
{
variant = wxString::Format(wxT("r.%d c.%d"), row, col);
}

virtual bool SetValue(const wxVariant &variant, unsigned int row,
unsigned int col)
{
return false;
}

};

// Main window.
class AppFrame : public wxFrame
{
public:
AppFrame() :
wxFrame(NULL, wxID_ANY, wxT("Second attempt to use wxDataView
(generated data)"))
{
// The bare-bone DataView -- no special functionality.
wxDataViewCtrl * pDataView = new wxDataViewCtrl(this, wxID_ANY);
MyDataViewModel * pModel = new MyDataViewModel();
pDataView->AssociateModel(pModel);

// All columns from the model.
for (unsigned int i = 0; i < pModel->GetColumnCount(); ++i)
{
wxString label(wxString::Format(wxT("column %d"), i));
pDataView->AppendTextColumn(label, i);
}
}
};


// The application.
class DataViewSample : public wxApp
{
public:
virtual bool OnInit()
{
AppFrame * frame = new AppFrame();
frame->Show(true);
return true;
}
};

// Create the global instance and call DataViewSample::OnInit().
IMPLEMENT_APP(DataViewSample)
======================================================


--
Petr Prikryl; prikryl at skil dot cz

Robert Roebling

unread,
Nov 15, 2007, 10:10:42 AM11/15/07
to wx-u...@lists.wxwidgets.org

Petr Prikryl wrote:


> #include "wx/wx.h"
> #include "wx/dataview.h"
>
> // Generated data for the DataView.
> class MyDataViewModel: public wxDataViewIndexListModel
> {
> public:
> virtual unsigned int GetColumnCount() const { return 50; }
> virtual unsigned int GetRowCount() { return 10000; }

You need to write

class MyDataViewModel: public wxDataViewIndexListModel
{
public:

MyDataViewModel() : wxDataViewIndexListModel( 10000 ) { }

which should probably be made clearer in the docs. This is
because I cannot call any virtual such as GetRowCount()
from the constructor of the base class.

I just tested your sample and I had to optimise the start
code of wxDataViewIndexListModel to make this work, this
is now rev. 49970. I just tested it under wxGTK, not under
wxMSW yet.

Thanks for giving the code a try.

Robert

Petr Prikryl

unread,
Nov 16, 2007, 4:57:22 AM11/16/07
to wx-u...@lists.wxwidgets.org
Thanks for being patient with me...

Robert Roebling:
> Petr Prikryl wrote:
> > [... wxDataViewIndexListModel generates
> > empty content wxDataViewCtrl...]
>
> You need to write [...]


> MyDataViewModel() : wxDataViewIndexListModel( 10000 ) { }
>
> which should probably be made clearer in the docs. This is
> because I cannot call any virtual such as GetRowCount()

> from the constructor of the base class. [...]

I see. It seems that the wxDataViewIndexListModel is not
what I am searching for. (Not your fault. ;)

Is there any model that could be used to replace
virtual list view control? Say, I want to display
much more lines. Have a look at the following sample
that does what I would like to be able to do with
the wxDataViewCtrl.

If there is no such model, is there any plan to implement it?

Thanks,
pepr

===========================================================
/* Virtual ListView sample -- a lot of generated rows (like
100.000.000). */

#include "wx/wx.h"
#include "wx/listctrl.h"

class MyListView : public wxListView
{
public:
MyListView(int count, wxWindow * parent):
wxListView(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize,
wxLC_REPORT | wxLC_VIRTUAL)
{
// Create the columns with labels.
wxListItem itemCol;
for (int i = 0; i < 10; ++i)
{
wxString label(wxString::Format(wxT("Column %d"), i));
itemCol.SetText(label);
InsertColumn(i, itemCol);
SetColumnWidth(i, 100);
}

// Tell the number of lines to be displayed.
SetItemCount(count);
};

private:
MyListView(); // Implicit constructor is forbiden.

virtual wxString OnGetItemText(long item, long column) const
{
return wxString::Format(wxT("r. %d, c. %d"), item, column);
}
//virtual int OnGetItemImage(long item) const { return 0; }
//virtual wxListItemAttr * OnGetItemAttr(long item) const { return
NULL; }
};


class AppFrame : public wxFrame
{
public:
AppFrame() :

wxFrame(NULL, wxID_ANY, wxT("Virtual ListView sample (generated
content)"))
{
MyListView * pListView = new MyListView(100000000, this);
}
};


// The application class.
class VirtualListViewSampleApp : public wxApp


{
public:
virtual bool OnInit()
{
AppFrame * frame = new AppFrame();
frame->Show(true);
return true;
}
};


// Create the global instance and call

VirtualListViewSampleApp::OnInit().
IMPLEMENT_APP(VirtualListViewSampleApp)
===========================================================

Robert Roebling

unread,
Nov 16, 2007, 9:42:38 AM11/16/07
to wx-u...@lists.wxwidgets.org

Petr Prikryl wrote:

> I see. It seems that the wxDataViewIndexListModel is not
> what I am searching for. (Not your fault. ;)

I tested your sample with 10000 row and it works fine now.

> Is there any model that could be used to replace
> virtual list view control? Say, I want to display
> much more lines. Have a look at the following sample
> that does what I would like to be able to do with
> the wxDataViewCtrl.
>
> If there is no such model, is there any plan to implement it?
>

> [..] a lot of generated rows (like 100.000.000).

Well 100.000.000 rows is a bit of a problem. The problem is
that we absolutely wanted to support the OS X databrowser
control so we had to follow its design. This has two
drastic design consequences: 1) you need to provide a unique
item ID for each item and need to "add" the items to the
OS X control using an array, which would be 400.000.000
bytes large 2) The OS X control displays the items by sorting
them (or arbitrarily). There is no "nth" item so in the
wxDataViewIndexListModel I have to map position to ID.

I don't know what you want to display, but with such enourmous
amounts of rows, you may have write your own control or use
wxListCtrl or maybe wxGrid. If your control only displays the
items and (maybe) allow selection, writing it yourself shouldn't
be hard. If you want complex data input, in-place editing and
variable formating plus native LnF, this will be more work :-)

Robert


Petr Prikryl

unread,
Nov 16, 2007, 11:26:45 AM11/16/07
to wx-u...@lists.wxwidgets.org
Robert Roebling:
> Petr Prikryl wrote:
>
> > [...] Is there any model that could be used to replace

> > virtual list view control? Say, I want to display
> > much more lines [like 100.000.000 ...].
>
> Well 100.000.000 rows is a bit of a problem. [...]

> we absolutely wanted to support the OS X databrowser
> control so we had to follow its design. [...] 1) you need
> to provide a unique item ID for each item and need to "add"
> the items to the OS X control using an array [...]
>
> I don't know what you want to display, [...]

Well, we display some user's database code lists.
The number of rows is not that big problem (the observed
extreme is about 200.000 rows). The problem is that
we display serveral of them at once and it takes some time
to fill the structures.

> but with such enourmous
> amounts of rows, you may have write your own control or use
> wxListCtrl or maybe wxGrid. If your control only displays the
> items and (maybe) allow selection, writing it yourself shouldn't
> be hard. If you want complex data input, in-place editing and
> variable formating plus native LnF, this will be more work :-)

Isn't the wxGrid deprecated now?

Well, I am dreaming about some easier version of
wxDataViewIndexListModel without the internal array and
the sorting capability... Say wxDataViewVirtualListModel?

Thanks,
pepr

Vadim Zeitlin

unread,
Nov 16, 2007, 11:30:54 AM11/16/07
to wx-u...@lists.wxwidgets.org
On Fri, 16 Nov 2007 15:42:38 +0100 Robert Roebling wrote:

RR> Well 100.000.000 rows is a bit of a problem.

This is a pity and personally I remain convinced that there must be some
way to support controls with "infinite" number of items under OS X too. I
just can't believe that the native data browser control is unsuitable for
displaying the database contents. But unfortunately I never had time to
learn its API myself and so I can't propose anything concrete. Still, I'm
willing to bet that we're missing something here.

RR> The problem is
RR> that we absolutely wanted to support the OS X databrowser
RR> control so we had to follow its design. This has two
RR> drastic design consequences: 1) you need to provide a unique
RR> item ID for each item and need to "add" the items to the
RR> OS X control using an array, which would be 400.000.000
RR> bytes large 2) The OS X control displays the items by sorting
RR> them (or arbitrarily). There is no "nth" item so in the
RR> wxDataViewIndexListModel I have to map position to ID.

At the very least, what about providing a model which does this internally
under OS X and doesn't penalize the other platforms?

Regards,
VZ

--
TT-Solutions: wxWidgets consultancy and technical support
http://www.tt-solutions.com/


H

unread,
Nov 17, 2007, 2:47:25 AM11/17/07
to wx-u...@lists.wxwidgets.org

In article <AemyuC.A....@brage.sunsite.dk>,
va...@wxwidgets.org (Vadim Zeitlin) wrote:

> On Fri, 16 Nov 2007 15:42:38 +0100 Robert Roebling wrote:
>
> RR> Well 100.000.000 rows is a bit of a problem.
>
> This is a pity and personally I remain convinced that there must be some
> way to support controls with "infinite" number of items under OS X too. I
> just can't believe that the native data browser control is unsuitable for
> displaying the database contents. But unfortunately I never had time to
> learn its API myself and so I can't propose anything concrete. Still, I'm
> willing to bet that we're missing something here.

There is no problem to support 100.000.000 rows but the native control
will become a bit slow. Though you do not have to provide data for all
100.000.000 entries you have to tell the (native) control that you have
that much data and you have to allocate at least IDs for that much
entries.
When the native control wants to display the 500.000th data set it will
request the model for data. This process is hidden for the user of
wxWidgets by the wxWidget API.

>
> RR> The problem is
> RR> that we absolutely wanted to support the OS X databrowser
> RR> control so we had to follow its design. This has two
> RR> drastic design consequences: 1) you need to provide a unique
> RR> item ID for each item and need to "add" the items to the
> RR> OS X control using an array, which would be 400.000.000
> RR> bytes large 2) The OS X control displays the items by sorting
> RR> them (or arbitrarily). There is no "nth" item so in the
> RR> wxDataViewIndexListModel I have to map position to ID.
>
> At the very least, what about providing a model which does this internally
> under OS X and doesn't penalize the other platforms?
>

"I have to map position to ID": This is done internally in
wxDataViewIndexListModel. So, nobody is penalized.

But if somebody does not need at all an index (like in database
applications) he can derive from wxDataViewModel and is therefore not
penalized to use indices (as it is the case for the wxListCtrl control).

So, basically the user of the wxWidget API can choose what he wants to
have.


> Regards,
> VZ

Therefore, if the original application from Petr is based on a database
application the use of indices is wrong or unnecessary.
Each database uses a unique ID to identify its data. This ID should be
used in wxDataViewModel to identify the data. Just tell wxDataViewModel
the IDs and you are done. This is the BIG benefit of wxDataViewModel
against wxListCtrl.
I am using wxDataViewModel this way in my application having also a
database and it works smoothly.

Hartwig

H

unread,
Nov 17, 2007, 2:51:43 AM11/17/07
to wx-u...@lists.wxwidgets.org

In article <E8AE1CAFC84D634A9CC...@skil01.skil.mistni>,

You are deriving from the wrong class. Use wxDataViewModel instead.

Please have a look at my previous posting. You do not need indices at
all for your application. Just use the IDs that are provided by the
database.
You also do not have to provide the data for all entries at once. This
is done by the API on demand.


> Thanks,
> pepr
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: wx-users-u...@lists.wxwidgets.org
> For additional commands, e-mail: wx-use...@lists.wxwidgets.org

Hartwig

Robert Roebling

unread,
Nov 17, 2007, 7:03:17 AM11/17/07
to wx-u...@lists.wxwidgets.org

> Isn't the wxGrid deprecated now?

No, it isn't.

> Well, I am dreaming about some easier version of
> wxDataViewIndexListModel without the internal array
> and the sorting capability... Say wxDataViewVirtualListModel?

The sorting is used only to tell OS X that the first
item is positioned at the top etc. It is not used for
any normal sorting (e.g. alphanumerical).

> Well, we display some user's database code lists.
> The number of rows is not that big problem (the
> observed extreme is about 200.000 rows). The problem
> is that we display serveral of them at once and it
> takes some time to fill the structures.

If you only display the database, then you should
probably write a small widget yourself that doesn't
use any IDs, has not sorting and just display row n
at position n.

Robert

Vadim Zeitlin

unread,
Nov 17, 2007, 9:08:52 AM11/17/07
to wx-u...@lists.wxwidgets.org
On Sat, 17 Nov 2007 08:47:25 +0100 H <H...@h.com> wrote:

H> There is no problem to support 100.000.000 rows but the native control
H> will become a bit slow.

Why? wxListCtrl isn't slower with 100.000.000 items than with 100.000 (or
10.000 for that matter).

H> Though you do not have to provide data for all 100.000.000 entries you
H> have to tell the (native) control that you have that much data and you
H> have to allocate at least IDs for that much entries.

This id allocation part is what I don't understand -- it's an O(N)
operation (both time- and memory usage wise) and so is just unacceptable
for a virtual control.

H> When the native control wants to display the 500.000th data set it will
H> request the model for data. This process is hidden for the user of
H> wxWidgets by the wxWidget API.

Apparently it's not hidden enough if you still need to preallocate the ids
for all N items. Or don't you? I'm confused because you and Robert seem to
say different things, notably you seem to think that wxDataViewCtrl can be
used for huge number of items while Robert recommends writing your own
control for this case (ugh).

H> So, basically the user of the wxWidget API can choose what he wants to
H> have.

Ok, so can we have an example in the dataview sample showing 100.000.000
items (and not 100 as MyListModel currently does)?

Thanks,

H

unread,
Nov 17, 2007, 11:42:12 AM11/17/07
to wx-u...@lists.wxwidgets.org

In article <cTLeLB.A....@brage.sunsite.dk>,
va...@wxwidgets.org (Vadim Zeitlin) wrote:

> On Sat, 17 Nov 2007 08:47:25 +0100 H <H...@h.com> wrote:
>
> H> There is no problem to support 100.000.000 rows but the native control
> H> will become a bit slow.
>
> Why? wxListCtrl isn't slower with 100.000.000 items than with 100.000 (or
> 10.000 for that matter).

wxListCtrl's speed strongly depends on the size UNLESS you overload some
of the methods to make a virtual control out of it. But the standard use
of wxListCtrl::InsertItem is quite slow.

>
> H> Though you do not have to provide data for all 100.000.000 entries you
> H> have to tell the (native) control that you have that much data and you
> H> have to allocate at least IDs for that much entries.
>
> This id allocation part is what I don't understand -- it's an O(N)
> operation (both time- and memory usage wise) and so is just unacceptable
> for a virtual control.
>

The native wxDataViewCtrl is not a virtual control in a sense that you
do not have to provide all the IDs. Therefore, you have to enter indeed
xxx ID entries. But you do not have to provide the data for all the
entries.

> H> When the native control wants to display the 500.000th data set it will
> H> request the model for data. This process is hidden for the user of
> H> wxWidgets by the wxWidget API.
>
> Apparently it's not hidden enough if you still need to preallocate the ids
> for all N items. Or don't you? I'm confused because you and Robert seem to
> say different things, notably you seem to think that wxDataViewCtrl can be
> used for huge number of items while Robert recommends writing your own
> control for this case (ugh).
>

Depends what huge is. 100.000.000 would be too big; but for normal
applications it works. I tested it with more than 10.000 entries only
though.

> H> So, basically the user of the wxWidget API can choose what he wants to
> H> have.
>
> Ok, so can we have an example in the dataview sample showing 100.000.000
> items (and not 100 as MyListModel currently does)?
>
> Thanks,
> VZ

Just add 100.000.000 IDs and you have it (if it works I do not know but
I tested it with 10.000 or more items). A native virtual control does
not exist on the Mac.
You can even not simulate it because you cannot fool drawing the
scrollbars of the native control.

Anyway it would hardly make sense with any standard GUI to try to
implement it because you are not able to navigate through the data:
assume you have a screen resolution in the vertical direction of 1000
pixels you have a resolution of 1.000.000 entries (by the usage of a
scrollbar; page up or page down functionality for 100.000.000 items also
does not really help). So, the practical limit for any standard GUI is
about 100.000 entries or below.
Having said that I think that the API of wxDataViewCtrl is superior to
wxListCtrl (report view). Therefore, I do not use wxListCtrl anymore.
But this might also be a matter of taste.

Hartwig

Robert Roebling

unread,
Nov 17, 2007, 4:11:47 PM11/17/07
to wx-u...@lists.wxwidgets.org

Vadim Zeitlin wrote:

> Robert Roebling wrote:
>
> RR> Well 100.000.000 rows is a bit of a problem.
>
> This is a pity and personally I remain convinced that there must be
> some way to support controls with "infinite" number of items under
> OS X too. I just can't believe that the native data browser control
> is unsuitable for displaying the database contents.

The answer to this question is quickly there if you look at
the Cocoa API. It has a virtual NSTableView for this purpose
and the NSBrowser that is behind the data browswer control.
The two controls are just different are used for different
purposes. The GTK+ developers have somehow managed to write
one control for both (they support both IDs and indeces),
but Carbon has only the ID based variant.

The control that Petr wants is almost exactly the control that
I initially wrote as wxDataViewListCtrl, i.e. virtual, row
based, tabular, not-tree-like.

This may indicate that we should also offer both as different
controls and I'm playing with the idea to implement a table view
as a generic control only. In theory, we could try to write a
wxTableView (or wxDataTableView) and have it use native GTK+
and native Cocoa code, but we don't know when wxCocoa will
be up to that. Also, the danger of introducing sutle inefficiencies
when going through the native layer is still there and could
be a real problem when displaying 10.000.000 lines. So how
about keeping the current ID based (wxDataViewItem based)
wxDataViewCtrl which will give native LnF for displaying
nearly anything in either tabular or tree-fashion or both
(but without being fully virtual) and offering a second
generic control with a similar API but virtual (in the sense
of being index based) and only tabular?

Robert


Vadim Zeitlin

unread,
Nov 18, 2007, 10:52:36 AM11/18/07
to wx-u...@lists.wxwidgets.org
On Sat, 17 Nov 2007 22:11:47 +0100 Robert Roebling wrote:

RR> So how
RR> about keeping the current ID based (wxDataViewItem based)
RR> wxDataViewCtrl which will give native LnF for displaying
RR> nearly anything in either tabular or tree-fashion or both
RR> (but without being fully virtual) and offering a second
RR> generic control with a similar API but virtual (in the sense
RR> of being index based) and only tabular?

Well, this obviously would increase (hopefully not double, but still) the
amount of work. And not having a "fully virtual" tree-like control would be
a pity too. Again, I don't want to give the impression that I care about
one program only, but OTOH I don't think this is such a special case
neither: when you present the mailbox contents, you do want to allow the
user to expand and collapse threads. But you do not want to allocate ids
for all the items because you already have perfectly valid ids for all of
them which are just the message numbers in the mailbox.

Regards,

H

unread,
Nov 18, 2007, 1:33:29 PM11/18/07
to wx-u...@lists.wxwidgets.org

In article <lKjeZ.A.p...@brage.sunsite.dk>,
va...@wxwidgets.org (Vadim Zeitlin) wrote:

You only have to supply IDs for the open containers (threads in your
e-mail case). So, if you have only - let's say 10 - containers that are
all closed and behind the 10 closed containers there a 10 000 000 items
you have to initially only provide the IDs of the 10 containers. But if
you expand all of them recursively you have to provide all IDs.

Hartwig

Robert Roebling

unread,
Nov 19, 2007, 9:34:39 AM11/19/07
to wx-u...@lists.wxwidgets.org

> > Well 100.000.000 rows is a bit of a problem. [...]
> > we absolutely wanted to support the OS X databrowser
> > control so we had to follow its design. [...] 1) you need
> > to provide a unique item ID for each item and need to "add"
> > the items to the OS X control using an array [...]
> >
> > I don't know what you want to display, [...]
>
> Well, we display some user's database code lists.
> The number of rows is not that big problem (the observed
> extreme is about 200.000 rows). The problem is that
> we display serveral of them at once and it takes some time
> to fill the structures.
>
> > but with such enourmous
> > amounts of rows, you may have write your own control or use
> > wxListCtrl or maybe wxGrid. If your control only displays the
> > items and (maybe) allow selection, writing it yourself shouldn't
> > be hard. If you want complex data input, in-place editing and
> > variable formating plus native LnF, this will be more work :-)
>
> Isn't the wxGrid deprecated now?
>
> Well, I am dreaming about some easier version of
> wxDataViewIndexListModel without the internal array and
> the sorting capability... Say wxDataViewVirtualListModel?

I just changed the implementation of the wxDataViewIndexListModel
class to be virtual under GTK+ und in generic code (MSW). Please
try your code again to see if it works with many item (it will).
I'm not sure if scrolling to a certain item can become difficult
or if other usablility problems will occur (refresh problems?),
but in general it works. The implementation under OS X is not
changed.

Further testing welcome.

Robert

Petr Prikryl

unread,
Nov 20, 2007, 4:23:16 AM11/20/07
to wx-u...@lists.wxwidgets.org
Hi Robert,

Thanks for your effort.

> I just changed the implementation of the wxDataViewIndexListModel
> class to be virtual under GTK+ und in generic code (MSW). Please
> try your code again to see if it works with many item (it will).
> I'm not sure if scrolling to a certain item can become difficult
> or if other usablility problems will occur (refresh problems?),
> but in general it works. The implementation under OS X is not
> changed.

I have updated to revision 50098 and compiled the same
example. The startup is fast now.

For ability to scroll to the wanted row (speaking also about
virtual ListView) -- it works as expected. It is clear that
one cannot navigate to any row by simply pulling the slider.
On the other hand, clicking below or above the slider (Windows)
moves one page, scroll wheel on the mouse also works...

I have observed some problems with the new wxDataViewIndexListModel
on Windows. I have used the example below, slightly modified
(to avoid guessing). The number of rows was set to 10 000 000.
I did compile it using Visual Studio 2005 and executed it
on Windows Vista.

The observed problems appear when I scroll down using the slider
to the row about 7 800 000 plus something. When tried to increase
the maximum to 100 000 000, the problematic rows have about the same
numbers -- i.e. it is absolute, not relative to the whole range.

When I move the slider slowly to the problematic rows, it seems
as if some events stop to work. When the slider is left on
the problematic position and you try to make the window more narrow
and then wider again, the client area is not repainted. Possibly
it is (because the scrolling wheel on the mouse makes a difference)
but it looks as if the control's area is not widened or narrowed
with the window. Also, clicking below and above the right slider
does nothing, PgUp/PgDn does not work, The Ctrl-End does not work,
but the Ctrl-Home does (as if the result was dependent on the final
position). The column can be widened using the column heading,
but the change is not propagated to the painted rows. Whenever
I move to the top (above the problematic rows). Everything seems
to work.

One more wish from me would be the ability to make the model
more similar to virtual ListView in the sense that I could
dynamically set the range -- the max number of rows (not to fix
the number of rows in the constructor). I understand that it
could change drastically the design of the class... Possibly,
it could be another class. I cannot explain now, but I feel
that for example "virtual ListView" approach is the right
example how to do that. It introduces the minimal functionality
(more generic, more flexible, more possibilities to use it for
final implementation). I wish that there would be one generic
virtual wxDataViewListModel with that kind of features.
It can be implemented in parallel with wxDataViewIndexListModel
or it could be its base class, whatever.

Hartwig said that I should use the wxDataViewModel base
class and do it on my own. However, I believe that a general
implementation wxDataViewModel for the list view should exist,
and that it should be less special than the wxDataViewIndexListModel.

Thanks again, Robert, for your work!
Petr


==================================================================
#include "wx/wx.h"
#include "wx/dataview.h"

// Generated data for the DataView.
class MyDataViewModel: public wxDataViewIndexListModel
{
public:

MyDataViewModel() : wxDataViewIndexListModel(10000000) { }


virtual unsigned int GetColumnCount() const { return 50; }

virtual unsigned int GetRowCount() { return 10000000; }


virtual wxString GetColumnType(unsigned int col) const { return
wxT("string"); }

virtual void GetValue(wxVariant &variant, unsigned int row, unsigned
int col) const
{
variant = wxString::Format(wxT("r.%d c.%d"), row, col);
}

virtual bool SetValue(const wxVariant &variant, unsigned int row,
unsigned int col)
{
return false;
}
};

// Main window.


class AppFrame : public wxFrame
{
public:
AppFrame() :

wxFrame(NULL, wxID_ANY, wxT("Second attempt to use wxDataView
(generated data)"))
{
// The bare-bone DataView -- no special functionality.
wxDataViewCtrl * pDataView = new wxDataViewCtrl(this, wxID_ANY);
MyDataViewModel * pModel = new MyDataViewModel();
pDataView->AssociateModel(pModel);

pModel->DecRef(); // !!! I did not noticed that earlier.
pModel = NULL; // ... and this will probably make it more
robust.

// All columns from the model.
for (unsigned int i = 0; i < pModel->GetColumnCount(); ++i)
{
wxString label(wxString::Format(wxT("column %d"), i));
pDataView->AppendTextColumn(label, i);
}
}
};


// The application.
class DataViewSample : public wxApp


{
public:
virtual bool OnInit()
{
AppFrame * frame = new AppFrame();
frame->Show(true);
return true;
}
};

// Create the global instance and call DataViewSample::OnInit().
IMPLEMENT_APP(DataViewSample)
==================================================================

H

unread,
Nov 20, 2007, 4:18:57 PM11/20/07
to wx-u...@lists.wxwidgets.org

In article <E8AE1CAFC84D634A9CC...@skil01.skil.mistni>,
Prik...@skil.cz ("Petr Prikryl") wrote:

I said it because using databases normally does not require to have an
index. Databases provide IDs and wxDataViewModel can use them directly.
If you need for whatever reason indices you should still use
wxDataViewIndexListModel.

> Thanks again, Robert, for your work!
> Petr

Hartwig

Robert Roebling

unread,
Nov 20, 2007, 5:16:58 PM11/20/07
to wx-u...@lists.wxwidgets.org

> The observed problems appear when I scroll down using the slider
> to the row about 7 800 000 plus something.

There is probably a 32-bit overflow somewhere. Windows cannot
scroll infinitely anywhere.


> One more wish from me would be the ability to make the model
> more similar to virtual ListView in the sense that I could
> dynamically set the range -- the max number of rows (not to fix
> the number of rows in the constructor).

You can currently add and delete individual rows efficiently
and for simply changing the number of rows, we'd have to
recreate the entire control/hash for wxMac and call a simple
refresh on other platforms, so I'll add this.

> I understand that it
> could change drastically the design of the class...

No.

> Hartwig said that I should use the wxDataViewModel base
> class and do it on my own. However, I believe that a general
> implementation wxDataViewModel for the list view should exist,
> and that it should be less special than the wxDataViewIndexListModel.

What do you mean? "In general should exist" is not an argument
in itself. Having a virtual tree-like control is more difficult
to achieve since you cannot any long map from wxDataViewItem
to line number. Actually, you can do that in the row-based
approach written by Bo in the generic code, but not for GTK+
and even less for OS X.

Robert

Petr Prikryl

unread,
Nov 21, 2007, 2:35:52 AM11/21/07
to wx-u...@lists.wxwidgets.org
Robert Roebling wrote:
> > The observed problems appear when I scroll down using the slider
> > to the row about 7 800 000 plus something.
>
> There is probably a 32-bit overflow somewhere. Windows cannot
> scroll infinitely anywhere.

Does wxDataViewCtrl for Windows use the same native control
as the wxListView control? The reason for asking is that wxListView
can handle the case with 10 000 000 rows smoothly, without problems.
If the answer is yes, then the overflow happens in the wxDataViewCtrl
or wxDataViewModel or in some related class.

> > [...] Hartwig said that I should use the wxDataViewModel base


> > class and do it on my own. However, I believe that a general
> > implementation wxDataViewModel for the list view should exist,
> > and that it should be less special than the
wxDataViewIndexListModel.
>
> What do you mean? "In general should exist" is not an argument
> in itself. Having a virtual tree-like control is more difficult
> to achieve since you cannot any long map from wxDataViewItem
> to line number. Actually, you can do that in the row-based
> approach written by Bo in the generic code, but not for GTK+
> and even less for OS X.

Sorry for the confusion (Robert and Hartwig). I do not know
details of combinations of the control and of the model.
If wxDataViewCtrl supports only tabular and tree forms, then
probably my "generally" is implemented in tabular behaviour
of the wxDataViewCtrl. What I excactly mean is handling scrollbars
and events related to moving inside the control. For this,
the model must give the control also the number of rows, right?

If the wxDataViewModel is to be used, how the control gets
the number of rows? Is it enough to derive my model only to
add a member and accessor methods for setting and getting
the number of rows?

Thanks,
Petr

P.S. Should I change the thread subject?

Robert Roebling

unread,
Nov 21, 2007, 9:03:23 AM11/21/07
to wx-u...@lists.wxwidgets.org

Petr Prikryl wrote:

> Robert Roebling wrote:
>
> > > The observed problems appear when I scroll down using the slider
> > > to the row about 7 800 000 plus something.
> >
> > There is probably a 32-bit overflow somewhere. Windows cannot
> > scroll infinitely anywhere.
>
> Does wxDataViewCtrl for Windows use the same native control
> as the wxListView control?

No, wxListCtrl under MSW is a native Win32 control.

> The reason for asking is that wxListView
> can handle the case with 10 000 000 rows smoothly, without problems.
> If the answer is yes, then the overflow happens in the wxDataViewCtrl
> or wxDataViewModel or in some related class.

I don't currently have time to look that up.

>
> > > [...] Hartwig said that I should use the wxDataViewModel base
> > > class and do it on my own. However, I believe that a general
> > > implementation wxDataViewModel for the list view should exist,
> > > and that it should be less special than the
> wxDataViewIndexListModel.
> >
> > What do you mean? "In general should exist" is not an argument
> > in itself. Having a virtual tree-like control is more difficult
> > to achieve since you cannot any long map from wxDataViewItem
> > to line number. Actually, you can do that in the row-based
> > approach written by Bo in the generic code, but not for GTK+
> > and even less for OS X.
>
> Sorry for the confusion (Robert and Hartwig). I do not know
> details of combinations of the control and of the model.
> If wxDataViewCtrl supports only tabular and tree forms, then
> probably my "generally" is implemented in tabular behaviour
> of the wxDataViewCtrl. What I excactly mean is handling scrollbars
> and events related to moving inside the control. For this,
> the model must give the control also the number of rows, right?
>
> If the wxDataViewModel is to be used, how the control gets
> the number of rows?

You call wxDataViewModel::ItemsAdded() which invokes notifiers
which in turn inform the native control. This should be mapped
to a similar call in wxDataViewListIndexModel, but currently
there are only methods in wxDataViewListIndexModel for adding
(prepending, inserting, appending) individual rows one by one.

So we need to extend the API to allow adding lots of items
or allow to simply reset the size (as you requested). This
is possible and indeed probably simple to do.

Robert

Reply all
Reply to author
Forward
0 new messages