2017-02-13 1 views
0

Ich entwickle eine App, die verwendet wird, um mit 20k + Elemente in WPF-Listbox angezeigt zu arbeiten, so dass sie offensichtlich in Seiten aufgeteilt werden müssen.Paging mit CreateDerivedCollection

Meine aktuelle Lösung ist ein bisschen laggy:

Ich beantrage einen Filter mit Asynchron-Befehl Paraller.ForEach auf alle Artikel und ich gesetzt MatchesFilter Eigenschaft. Das funktioniert gut:

Dies ist schnell, hält die Benutzeroberfläche ansprechend und Sie können sehen, wie sich der Count in WPF Label schnell ändert.

Wenn Ende Filterung, ich (auf Hauptthread):

Items.Clear(); 
foreach (var s in FilteredItems.Skip((CurrentPage - 1) * temsPerPage).Take(ItemsPerPage)) 
         Items.Add(s); 

Und das ist, wo mein Problem ist. Jedes Element wird zusammen mit einem Bild angezeigt, das asynchron von einer URL geladen wird. Der Clear() Teil friert die Benutzeroberfläche auf merkliche Weise ein. Ich habe 250 Artikel pro Seite (es sollte nicht weniger sein, weil der Benutzer in der Lage sein sollte, anhand des Bildes mit seinem Auge nach einem Gegenstand zu suchen).

Gibt es einen besseren Weg, dies zu tun? Ich weiß, über DynamicData, aber das nutzt RxUI 6.x.

Antwort

2

können Sie verwenden Dynamic mit RxUI 7.0

+0

Ich bekomme Fehler beim Verweisen Reactive.Interfaces 2.5.5. Welche Version sollte ich verwenden? –

+0

Die neueste Version auf 4.x, da sie auf Rx 2.x basiert. https://www.nuget.org/packages/DynamicData/4.10.1.1194 – Erlend

+0

Danke. Nur aus Neugier, ist es möglich, in reinem RxUI zu erreichen? –

0

Dynamic Data 4 mit RxUI 6.5 funktioniert gut und es ist das, was ich in der Regel verwenden. Davon abgesehen wollte ich einfach ein Code-Sample mit RxUI veröffentlichen. Hauptsächlich, weil Sie nicht löschen und dann neu hinzufügen müssen, um die DerivedList zu aktualisieren.

[TestMethod] 
    [TestCategory("Reactive")] 
    public async Task PagingReactiveUITest() 
    { 

     ReactiveList<int> SourceList = new ReactiveList<int>(); 
     for (int i = 0; i < 100; i++) 
     { 
      SourceList.Add(i); 
     } 

     Tuple<int, int> pageWindow = new Tuple<int, int>(0, 10); 


     //ReactiveComamnd that triggers paging 
     ReactiveCommand<Unit> updatePaging = 
      ReactiveCommand.CreateAsyncObservable<Unit>((_) => 
      { 

       pageWindow = new Tuple<int, int>(10, 20); 
       return Observable.Return(Unit.Default); 
      }); 


     var PagedList = 
      SourceList 
      .CreateDerivedCollection(
       x => x, 
       filter: (item) => item >= pageWindow.Item1 && item < pageWindow.Item2, 
       signalReset: updatePaging); 



     Assert.AreEqual(PagedList.First(), 0); 
     Assert.AreEqual(PagedList.Last(), 9); 

     //Trigger Paging 
     await updatePaging.ExecuteAsync(null); 

     Assert.AreEqual(PagedList.First(), 10); 
     Assert.AreEqual(PagedList.Last(), 19); 
    } 

Noch ein Hinweis .. Wenn Sie tun eine Menge Änderungen an einer Liste planen Sie auch Dinge tun können wie

using (SourceList.SuppressChangeNotifications()) 
{ 
     //DO STUFF 
} 

Welche Meldungen aus gehen an die UI stoppen, bis Sie fertig sind Verwirrung mit der Liste

+0

Ihre Lösung wäre großartig, wenn die Transformationsfunktion (oder Filterfunktion) wie folgt aussehen würde (x, i) => neues Tupel (i, x). Dann ja, aber leider ist das nicht der Fall. –

+0

Nun, der Filter und der Tuple können wirklich alles sein. Es war eher ein künstliches Beispiel, um Ihnen einige zusätzliche Funktionen zu zeigen, ohne die Liste löschen und neu auffüllen zu müssen. Sie können nach dem Index des Elements in der Filterfunktion suchen, um zu sehen, ob es sich um Ihre Paging-Anforderungen handelt. SuppressChangeNotifications könnte auch nützlich sein, um die UI nicht "einzufrieren" .... Das heißt, wenn Ihre Quellliste ziemlich groß ist, denke ich nicht, dass es irgendetwas in RxUI gibt, das die abgeleitete Liste im Vergleich zu DyamicData super effizient aktualisieren wird. –

+0

Ja, ich habe gerade 20k Probe getestet und sogar mit DynamicData es Weg zu langsam. Jetzt mache ich manuelle Filterung und Innenbefehl mit PLINQ und befülle dann die finale Artikelliste. Ich habe auch SuppressChangeNotifications und UI Freezes für kürzere Zeit verwendet, aber es ist immer noch bemerkbar. Zumindest jetzt, wenn ich Seiten wechsele oder etwas in Filterbox schreibe, ist es verwendbar. Danke für die Einsichten –