5

LargeIcons ビューで、仮想モードで動作するリストビューがあります。取得にはコストがかかるため、表示されているすべてのアイテムのデータを要求したいと考えています。表示されているアイテムの開始インデックスと合計数を取得するにはどうすればよいですか?

更新: CacheVirtualItems イベントを認識しています。私たちが使用しているサードパーティのデータベースは、1 つのレコードを取得するのに ~3 秒かかりますが、1000 のレコードを取得するには ~4 秒かかるため、大きなブロックで実行する必要があります。表示されているレコードが取得したレコードに含まれていることを確認する必要があるため、表示されているアイテムの開始インデックスと合計数を知る必要があります。それが不可能な場合は、回避策を見つける必要があります (おそらく、大量の画像セルを持つ DataGridView を使用して LargeIcons ビューを模倣する必要があります) が、可能であればこれを適切に行いたいと考えています。

4

7 に答える 7

3

本当の答えは次のとおりです。
* ListView の ScrollViewer を取得します。
* ScrollViewer.VerticalOffset は、最初に表示されるアイテムのインデックスです。
* ScrollViewer.ViewportHeight は、表示されるアイテムの数です。

ScrollViewer を取得するには、ListView の子内を検索する関数 FindDescendant(FrameworkElement, Type) が必要です。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)
于 2012-06-25T16:15:47.790 に答える
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;
}
于 2008-12-17T11:31:17.857 に答える
1

表示されていないアイテムに到達するまで、それらの可視性をチェックしながら、後続のアイテムを反復処理できます。これにより、表示されているアイテムの数が表示されます。

たとえば、次のようなものです。

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

ただし、ソートがこれにどのような影響を与えるかはわかりません。

于 2008-12-16T17:24:45.477 に答える
0

CacheVirtualItems イベントを見たことがありますか? コントロールは、1 つずつではなく、一連の項目を要求します。トー、スクロールする場合、一度に1つだけを要求する場合があります。ただし、ページダウン/ページアップはキャッシュメカニズムをトリガーします。

于 2008-12-16T20:09:01.900 に答える
0

私はこの投稿が古いことを知っています.....間違っています

MyScrollViewer = FindDescendant(MyListView, ScrollViewer)

右は:

Dim Myscrollviwer As ScrollViewer

Myscrollviwer = FindDescendant(myListView3, GetType(ScrollViewer))
MsgBox(Myscrollviwer.VerticalOffset)
于 2016-10-16T19:07:26.787 に答える
-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
于 2012-01-10T04:29:01.743 に答える
-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;

}
于 2011-05-30T14:18:54.690 に答える