tags:

views:

983

answers:

3

I have a listview working in virtual mode, in the LargeIcons view. Retrieves are expensive, so I want to ask for the data for all the visible items. How do I get the start index and total number of the visible items?

Update: I am aware of the CacheVirtualItems event. The third-party database we're using takes ~3s to retrieve a single record, but ~4s to retrieve a thousand records, so I have to do them in large blocks. I need to make sure the visible records are among those we retrieve, so I need to know the start index and total number of the visible items. If that's not feasible, I'll have to find a workaround (which will probably involve using a DataGridView with a load of image cells to imitate the LargeIcons view) but I would like to do this properly if possible.

A: 

You could iterate through subsequent items, checking their visibility until you reach the one that isn't visible. This would give you a count of the visible items.

For example, something like:

        for (int index = 0; index < list.Items.Count; index++)
        {
            if (list.ClientRectangle.IntersectsWith(item.GetBounds(ItemBoundsPortion.Entire)))
            {
                // Add to the list to get data.
            }
            else
            {
                // We got them all.
                break;
            }
        }

I'm not sure what effect sorting would have on this though.

Jeff Yates
A: 

Have you seen the CacheVirtualItems event? The control will ask for a range of items instead of one-by-one. Tho, if scrolling, it still may ask for only one at a time. But pagedown/up will trigger the cache mechanism.

Joel Lucsy
+1  A: 

Just off the top of my head, and I haven't tested this but could you do:

private void GetIndexes(ListView vv, out int startidx, out int count)
{
            ListViewItem lvi1 = vv.GetItemAt(vv.ClientRectangle.X+6, vv.ClientRectangle.Y + 6); 
            ListViewItem lvi2 = vv.GetItemAt(vv.ClientRectangle.X+6, vv.ClientRectangle.Bottom-10); 
            startidx = vv.Items.IndexOf(lvi1); 
            int endidx = vv.Items.IndexOf(lvi2);
            if (endidx == -1) endidx = vv.Items.Count;
            count = endidx - startidx;
}
WOPR