2015-12-23 1 views
0

Я пытаюсь создать «бесконечный прокручиваемый календарь». Моя идея - генерировать запрошенную часть календаря «на лету», так как ItemsSource i использует пользовательский класс WeekList, который реализует IList. При инициализации я вычисляю интервал вокруг текущей даты (5-летний радиус на данный момент, позже я хочу перейти до IntMax). Оттуда я просто вычислил запрошенные недели по индексу.GetEnumerator: связанный с процедурно сгенерированным списком в listbox с виртуализацией

я реализовал метод Item только создать данные о спросе и GetEnumerator следующим образом:

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

При попытке понять, что выход делает я был под впечатлением, что это будет только вычислять детали по мере необходимости.

Функционально календарь работает отлично, но при привязке WeekList Weekends к датам ListBox.ItemsSource все недели генерируются сразу.

EDIT: Я изолировали проблему в полном примере кода:

Мой MainWindow Code-Behind:

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 

А класс процедурно генерировать список заданных размеров:

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 единиц) создается во время привязки. Как я могу добиться того, что перечисляется только «видимая часть»? У меня создалось впечатление, что именно это делает ListBox с виртуализацией, поэтому я подозреваю, что я не понимаю, как GetEnumerator/Yield является виновником.

ответ

0

Реализация IList интерфейс вместо только IEnumerator решена проблема virutalization в моем примере. Я буду работать оттуда до моего полного решения, чтобы понять, что случилось.

Дополнительная информация: Моя настоящая проблема заключалась в том, что у меня был стиль с DataTrigger, который неявно манипулировал высотой ItemContainer. Наличие изменения размера ItemContainer эффективно отключает виртуализацию.