如何获取ListView中的可见项的起始索引和数量?

我在LargeIcons视图中有一个在虚拟模式下工作的listview。 检索很昂贵,所以我想询问所有可见项目的数据。 如何获取可见项目的起始索引和总数?

更新:我知道CacheVirtualItems事件。 我们使用的第三方数据库需要大约3秒来检索单个记录,但是需要大约4秒来检索一千条记录,所以我必须在大块中执行它们。 我需要确保可见记录在我们检索的记录中,因此我需要知道可见项的起始索引和总数。 如果这不可行,我将不得不找到一个解决方法(这可能涉及使用带有大量图像单元的DataGridView来模仿LargeIcons视图)但我想尽可能正确地做到这一点。

就在我的头顶,我没有测试过这个,但你能做到:

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; } 

您可以遍历后续项目,检查其可见性,直到找到不可见的项目。 这将为您提供可见项目的计数。

例如,类似于:

  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; } } 

我不确定排序会对此产生什么影响。

真正的答案是:
*获取ListView的ScrollViewer。
* ScrollViewer.VerticalOffset是第一个显示项的索引。
* ScrollViewer.ViewportHeight是显示的项目数。

要获取ScrollViewer,您需要一个函数FindDescendant(FrameworkElement,Type),它将在ListView的子元素中进行搜索。 加载Window后调用它。

VB.Net和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) 

你见过CacheVirtualItems事件了吗? 控件将询问一系列项目而不是一个一个。 如果滚动,它仍然可能一次只要求一个。 但是pagedown / up将触发缓存机制。

我知道这篇文章很老…..错了

 MyScrollViewer = FindDescendant(MyListView, ScrollViewer) 

权利是:

 Dim Myscrollviwer As ScrollViewer Myscrollviwer = FindDescendant(myListView3, GetType(ScrollViewer)) MsgBox(Myscrollviwer.VerticalOffset) 
 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; } 

试试这个:

 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