GetEnumerator:通过虚拟化将程序生成的列表绑定到列表框

GetEnumerator: binding procedurally generated list to listbox with virtualization

我正在尝试制作 "infinite scrollable calendar"。我的想法是动态生成日历的请求部分,因此作为 ItemsSource,我使用实现 IList 的自定义 class WeekList。 初始化后,我计算当前日期周围的时间间隔(目前为 5 年半径,稍后我想在 IntMax 允许的范围内)。 从那以后,我只是根据索引计算请求的周数。

我已经实现了仅按需创建数据的 Item 方法和 GetEnumerator,如下所示:

Public Iterator Function GetEnumerator1() As IEnumerator Implements IEnumerable.GetEnumerator
    For i As Integer = 1 To _Count
        Yield Item(i)
    Next
End Function

在尝试了解 Yield 时,我的印象是这只会根据需要计算 Items。

日历功能完美,但在将 WeekList "Dates" 绑定到 ListBox.ItemsSource 后,所有周都会立即生成。

编辑: 我已经在完整的代码示例中隔离了问题:

我的主窗口代码隐藏:

Class MainWindow
Public Sub New()

    ' This call is required by the designer.
    InitializeComponent()

    ' Add any initialization after the InitializeComponent() call.
    Me.DataContext = Me
End Sub


Private _TestList As VirtList
Public ReadOnly Property TestList As VirtList
    Get
        If _TestList Is Nothing Then
            _TestList = New VirtList(10000)
        End If
        Return _TestList
    End Get
End Property
End Class

和 class 程序生成给定大小的列表:

Public Class VirtList
Implements IEnumerable

Private _Count As Integer
Public Sub New(size As Integer)
    _Count = size
End Sub

Private _Items As New Dictionary(Of Integer, String)

Private Function Item(i As Integer) As String
    If Not _Items.ContainsKey(i) Then
        _Items(i) = "I am Item Number " & i
        Debug.Print("Current Cache Size: {0}", _Items.Count)
    End If
    Return _Items(i)
End Function

Public Iterator Function GetEnumerator() As IEnumerator Implements IEnumerable.GetEnumerator
    For i As Integer = 0 To _Count
        Yield Item(i)
    Next
End Function
End Class

在我的MainWindow.xaml

        <ListBox 
        VirtualizingPanel.IsVirtualizing="True"
        ItemsSource="{Binding TestList}"/>

整个列表(所有 10.000 个项目)在绑定时生成。我怎样才能实现只枚举 "visible portion" ?我的印象是,这正是 ListBox 对虚拟化所做的,所以我怀疑我对 GetEnumerator/Yield 的不理解是罪魁祸首。

实施 IList 接口 而不是仅实施 IEnumerator 解决了我示例中的虚拟化问题。我将从那里倒退到我的完整解决方案,看看有什么问题。

附加信息: 我真正的问题是我有一个带有隐式操纵 ItemContainer 高度的 DataTrigger 的 Style。 ItemContainer 大小的变化有效地禁用了虚拟化。