How to get the starting index and the number of visible items in a ListView?

I have a listview working in virtual mode in a LargeIcons view. Take out the costs, so I want to request data for all visible elements. How to get the starting index and the total number of visible elements?

Update: I am aware of the CacheVirtualItems event. The third-party database we use takes ~ 3 s to retrieve one record, but ~ 4s to retrieve thousands of records, so I have to do them in large blocks. I need the visible entries to be among the ones we retrieve, so I need to know the starting index and the total number of visible items. If this is not feasible, I will have to find a workaround (which is likely to involve using a DataGridView with loading image cells to simulate the LargeIcons view), but I would like to do it right, if possible.

+3
source share
7 answers

On top of my head, and I have not 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; } 
+1
source

You can iterate over subsequent elements, checking their visibility, until you reach what is not visible. This will give you the number of 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 if this would affect the sorting of effects.

0
source

Have you seen the CacheVirtualItems event? The control will request a series of elements instead of one. Tho, if scrolling, it can still only request one at a time. But pagedown / up will cause a caching mechanism.

0
source

REAL Answer:
* get ScrollViewer from ListView.
* ScrollViewer.VerticalOffset is the index of the first item shown.
* ScrollViewer.ViewportHeight is the number of items to display.

To get the ScrollViewer, you will need a function, FindDescendant (FrameworkElement, Type), which will search within the children View the list. Call it after loading the window.

Code in VB.Net and C #:

 Public Function FindDescendant(ByVal MyElementToSeek As FrameworkElement, _ ByVal TypeToFind As Type) As FrameworkElement If MyElementToSeek Is Nothing Then Return Nothing If MyElementToSeek.GetType() = TypeToFind Then Return MyElementToSeek For i = 0 To VisualTreeHelper.GetChildrenCount(MyElementToSeek) - 1 Dim OneChild = TryCast(VisualTreeHelper.GetChild(MyElementToSeek, i), FrameworkElement) Dim Result = FindDescendant(OneChild, TypeToFind) If Result IsNot Nothing Then Return Result Next Return Nothing End Function 

.

 public FrameworkElement FindDescendant(FrameworkElement MyElementToSeek, Type TypeToFind) { if (MyElementToSeek == null) return null; if (MyElementToSeek.GetType() == TypeToFind) return MyElementToSeek; for (i = 0; (i<= (VisualTreeHelper.GetChildrenCount(MyElementToSeek) - 1)); i++) { object OneChild = TryCast(VisualTreeHelper.GetChild(MyElementToSeek, i), FrameworkElement); object Result = FindDescendant(OneChild, TypeToFind); if (Result) return Result; } return null; } } ' MyScrollViewer = FindDescendant(MyListView, ScrollViewer) 
0
source

I know this post is old ..... Wrong

 MyScrollViewer = FindDescendant(MyListView, ScrollViewer) 

To the right:

 Dim Myscrollviwer As ScrollViewer Myscrollviwer = FindDescendant(myListView3, GetType(ScrollViewer)) MsgBox(Myscrollviwer.VerticalOffset) 
0
source
 foreach (var t in listView1.Items) { var lvitem = listView1.ItemContainerGenerator.ContainerFromItem(t) as ListViewItem; if (lvitem == null) continue; //lvitem will = null if it is not visible // otherwise do stuff with lvitem such as: lvitem.Foreground = Brushes.Green; } 
-one
source

Try the following:

 If ListView.Items.Count > 0 Then Dim lvi As ListViewItem = ListView.TopItem If lvi Is Nothing Then Return Dim startIndex As Integer = lvi.Index Dim lastVisible As Integer = startIndex While ListView.Items(lastVisible).Bounds.Bottom < Me.lvRes.Bounds.Bottom lastVisible += 1 End While lastVisible -= 1 End If 
-one
source

All Articles