Problem on loading a dialog box.

D

Dom

In my application, the user can bring up a dialog box that contains a
listbox. The listbox has about 6000 items, obtained by reading a
table in a Database. The dialog box is brought up every minute or so,
and I do not want the user to wait for that dialog box to rebuild the
listbox each time.

I see this done often enough. For example, in the CSharp studio
itself, the intellisense window pops up regularly, without a moment's
pause, and it contains much more than 6000 items. I assume the box is
being built just once, and then the popping on and off is just a
matter of making it visible and invisible.

How do I do this? Right now, the dialog box is never disposed in the
calling procedure. I just have a static variable that holds it, and
then I call frmWindow.ShowDialog (this), when I need it. And when the
user gives an answer, I call this.Close() to end it.

But still there is a pause, and using the debugger, I can see that the
dialog box is calling each items ToString() method, so I assume this
is being done just to repaint the listbox. Is there a better way?
 
M

mick

Dom said:
In my application, the user can bring up a dialog box that contains a
listbox. The listbox has about 6000 items, obtained by reading a
table in a Database. The dialog box is brought up every minute or so,
and I do not want the user to wait for that dialog box to rebuild the
listbox each time.

I see this done often enough. For example, in the CSharp studio
itself, the intellisense window pops up regularly, without a moment's
pause, and it contains much more than 6000 items. I assume the box is
being built just once, and then the popping on and off is just a
matter of making it visible and invisible.

How do I do this? Right now, the dialog box is never disposed in the
calling procedure. I just have a static variable that holds it, and
then I call frmWindow.ShowDialog (this), when I need it. And when the
user gives an answer, I call this.Close() to end it.

But still there is a pause, and using the debugger, I can see that the
dialog box is calling each items ToString() method, so I assume this
is being done just to repaint the listbox. Is there a better way?

Have you tried using Hide() instead of Close()?

mick
 
D

Dom

Have you tried using Hide() instead of Close()?

mick- Hide quoted text -

- Show quoted text -

Yes, I have. The same thing happens, plus, after the Hide(), the
focus does not always go back to the parent window. Sometimes it goes
to a different application running at the same time, and the user
needs to go to the task bar.

Dom
 
D

Dom

[...]
How do I do this?  Right now, the dialog box is never disposed in the
calling procedure.  I just have a static variable that holds it, and
then I call frmWindow.ShowDialog (this), when I need it.  And when the
user gives an answer, I call this.Close() to end it.
But still there is a pause, and using the debugger, I can see that the
dialog box is calling each items ToString() method, so I assume this
is being done just to repaint the listbox.  Is there a better way?
Have you tried using Hide() instead of Close()?

A modal Form (as here) is only ever actually hidden when the Close() method
is called anyway.

As far as the original question goes: the bottom line is that 6000 items is
a HUGE number of items for any ListBox to contain, and for any user to have
to navigate.

I don't recall seeing any Intellisense window that contained even that
many, never mind "much more than" that many.  However, for situations where
this amount of data is going to be displayed (whether it's a good idea or
not...sometimes it is, but more often it's not), the usual approach for
performance is to "virtualize" the display of the items.

That is, rather than having a control that is fully populated with a large
number of items all at once, have a program-maintained data structure
containing just the minimal amount of data necessary (e.g. an array of
strings themselves), and then reference that data structure as needed to
draw the individual items in the control (i.e. rather than expecting the
control to not only maintain the whole list of data items and also to
convert from a non-string object to a string in real-time as the control is
drawn).

At the very least, the OP should populate the ListBox with actual string
objects, not some other object that needs its ToString() method called for
display. And to really handle that number of list items efficiently, they
should look into "owner-draw" items, or even a fully custom implementation
of a list box where they have full control over the entire rendering code
path.

Pete

Some good ideas, here. I'll think about virtualizing the listbox, and
using strings instead of Class.ToString(). For the sake of my
reputation, let me add a few points:

1. The user types into a text box. The list box scrolls around to
keep track of the typing, as is done in Intellisense. The user does
not acutally use the scroll bar to find an item.

2. Intellisense seems to have several thousand items. First there is
the top level item list, then when the "dot" is typed, you have the
second level items, and so on. At some point, all those items are
stored, although maybe several different boxes are used.
 
D

Dom

[...]
How do I do this?  Right now, the dialog box is never disposed in the
calling procedure.  I just have a static variable that holds it, and
then I call frmWindow.ShowDialog (this), when I need it.  And whenthe
user gives an answer, I call this.Close() to end it.
But still there is a pause, and using the debugger, I can see that the
dialog box is calling each items ToString() method, so I assume this
is being done just to repaint the listbox.  Is there a better way?
Have you tried using Hide() instead of Close()?
A modal Form (as here) is only ever actually hidden when the Close() method
is called anyway.
As far as the original question goes: the bottom line is that 6000 items is
a HUGE number of items for any ListBox to contain, and for any user to have
to navigate.
I don't recall seeing any Intellisense window that contained even that
many, never mind "much more than" that many.  However, for situationswhere
this amount of data is going to be displayed (whether it's a good idea or
not...sometimes it is, but more often it's not), the usual approach for
performance is to "virtualize" the display of the items.
That is, rather than having a control that is fully populated with a large
number of items all at once, have a program-maintained data structure
containing just the minimal amount of data necessary (e.g. an array of
strings themselves), and then reference that data structure as needed to
draw the individual items in the control (i.e. rather than expecting the
control to not only maintain the whole list of data items and also to
convert from a non-string object to a string in real-time as the control is
drawn).
At the very least, the OP should populate the ListBox with actual string
objects, not some other object that needs its ToString() method called for
display. And to really handle that number of list items efficiently, they
should look into "owner-draw" items, or even a fully custom implementation
of a list box where they have full control over the entire rendering code
path.

Some good ideas, here.  I'll think about virtualizing the listbox, and
using strings instead of Class.ToString().  For the sake of my
reputation, let me add a few points:

1.  The user types into a text box.  The list box scrolls around to
keep track of the typing, as is done in Intellisense.  The user does
not acutally use the scroll bar to find an item.

2.  Intellisense seems to have several thousand items.  First there is
the top level item list, then when the "dot" is typed, you have the
second level items, and so on.  At some point, all those items are
stored, although maybe several different boxes are used.- Hide quoted text -

- Show quoted text -

Sorry, I can't use strings. I need the class itself. When a user
selects an item from the box, I need other information on that item.
Would using a data structure of some sort be much faster?
 
D

Dom

On May 15, 10:32 am, Peter Duniho <[email protected]>
wrote:
]
How do I do this?  Right now, the dialog box is never disposed in the
calling procedure.  I just have a static variable that holds it,and
then I call frmWindow.ShowDialog (this), when I need it.  And when the
user gives an answer, I call this.Close() to end it.
But still there is a pause, and using the debugger, I can see thatthe
dialog box is calling each items ToString() method, so I assume this
is being done just to repaint the listbox.  Is there a better way?
Have you tried using Hide() instead of Close()?
A modal Form (as here) is only ever actually hidden when the Close() method
is called anyway.
As far as the original question goes: the bottom line is that 6000 items is
a HUGE number of items for any ListBox to contain, and for any user to have
to navigate.
I don't recall seeing any Intellisense window that contained even that
many, never mind "much more than" that many.  However, for situations where
this amount of data is going to be displayed (whether it's a good idea or
not...sometimes it is, but more often it's not), the usual approach for
performance is to "virtualize" the display of the items.
That is, rather than having a control that is fully populated with a large
number of items all at once, have a program-maintained data structure
containing just the minimal amount of data necessary (e.g. an array of
strings themselves), and then reference that data structure as neededto
draw the individual items in the control (i.e. rather than expecting the
control to not only maintain the whole list of data items and also to
convert from a non-string object to a string in real-time as the control is
drawn).
At the very least, the OP should populate the ListBox with actual string
objects, not some other object that needs its ToString() method called for
display. And to really handle that number of list items efficiently, they
should look into "owner-draw" items, or even a fully custom implementation
of a list box where they have full control over the entire rendering code
path.
Pete
Some good ideas, here.  I'll think about virtualizing the listbox, and
using strings instead of Class.ToString().  For the sake of my
reputation, let me add a few points:
1.  The user types into a text box.  The list box scrolls around to
keep track of the typing, as is done in Intellisense.  The user does
not acutally use the scroll bar to find an item.
2.  Intellisense seems to have several thousand items.  First thereis
the top level item list, then when the "dot" is typed, you have the
second level items, and so on.  At some point, all those items are
stored, although maybe several different boxes are used.- Hide quoted text -
- Show quoted text -

Sorry, I can't use strings.  I need the class itself.  When a user
selects an item from the box, I need other information on that item.
Would using a data structure of some sort be much faster?- Hide quoted text -

- Show quoted text -

I did the virtualize bit. Works like a charm. Thanks, Peter, for the
advice.

Dom
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top