2008-12-16 102 views
3

我有一個工作在虛擬模式下,在LargeIcons視圖中的列表視圖。檢索是昂貴的,所以我想要詢問所有可見項目的數據。我如何獲得可見項目的開始索引和總數?如何獲取ListView中的開始索引和可見項目的數量?

更新:我知道CacheVirtualItems事件。我們使用的第三方數據庫需要花費大約3秒才能檢索一條記錄,但大約需要4秒才能檢索到一千條記錄,因此我必須以大塊的方式進行處理。我需要確保可見記錄在我們檢索的那些記錄中,所以我需要知道可見項目的開始索引和總數。如果這不可行,我必須找到一種解決方法(這可能會涉及使用DataGridView和一系列圖像單元來模擬LargeIcons視圖),但我希望在可能的情況下正確執行此操作。

+0

你的問題的標題,並在正文不要的問題讀同樣的東西。標題聽起來像你想要的開始索引和行數,但在它的問題,它讀取像你想每個行的數據是不同的問題。 – Jbecwar 2012-12-11 15:24:21

+0

它是前一段時間,但它是我需要的索引和數字。正如問題中提到的,我使用的是第三方數據庫,因此我不希望任何人回答關於在數據庫中沒有更多ino的情況下獲取數據的問題。 – Simon 2012-12-11 17:56:25

回答

0

您可以遍歷後續項目,檢查它們的可見性,直到達到不可見爲止。這會給你一個可見項目的計數。

例如,像:

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

我不知道會對這雖然什麼影響排序。

0

你見過CacheVirtualItems事件嗎?控制器會要求一系列物品,而不是一個接一個。如果滾動,它仍然可能一次只請求一個。但pagedown/up會觸發緩存機制。

+0

不回答問題 – erict 2016-05-03 19:38:30

1

剛剛送走我的頭頂,我沒有測試過這一點,但你可以這樣做:

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

你能解釋神奇的數字嗎? – gonzobrains 2012-12-06 23:47:12

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

} 
+0

OP聲明他的列表框處於虛擬模式。如果處於虛擬模式,訪問Items集合將引發異常(來源:https://msdn.microsoft.com/en-us/library/system.windows.forms.listview.virtualmode(v=vs.110).aspx,最後一段在備註中) – erict 2016-05-03 19:37:00

-1

試試這個:

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 
+0

OP聲明他的列表框處於虛擬模式。如果處於虛擬模式,訪問Items集合將引發異常(來源:https://msdn.microsoft.com/en-us/library/system.windows.forms.listview.virtualmode(v=vs.110).aspx,最後一段在備註中) – erict 2016-05-03 19:38:06

0

真正的答案是:
*獲取ListView的ScrollViewer。
* ScrollViewer.VerticalOffset是第一個顯示項目的索引。
* ScrollViewer.ViewportHeight是顯示的項目數。

爲了得到ScrollViewer中,您將需要一個功能, FindDescendant(FrameworkElement的,類型)將在 的ListView的孩子的內搜索 。窗口加載後調用它。

代碼在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) 
0

我知道這個帖子是老..... 錯誤

MyScrollViewer = FindDescendant(MyListView, ScrollViewer) 

右爲:

Dim Myscrollviwer As ScrollViewer 

Myscrollviwer = FindDescendant(myListView3, GetType(ScrollViewer)) 
MsgBox(Myscrollviwer.VerticalOffset) 
相關問題