Ich implementiere eine Liste, die leicht 10.000 kleine Bilder enthalten könnte. Der aktuelle Anwendungsfall zeigt eine Liste von Miniaturansichten eines Videos, so dass Sie durch ein Video Bild für Bild blättern können. Ich habe alle zwei Drittelsekunden im Video ein Miniaturbild des Videos in die Liste eingefügt. Ich muss sehr lange Videos (z. B. 1-Stunden-Video) unterstützen.
Also Virtualisierungsoptionen:
Ich habe versucht "Inkrementelle Datenvirtualisierung" und das verbraucht zu viel Speicher für mich, weil die Bilder nur über Streams angesprochen werden können und ich am Ende 10.000 Streams öffnen würde. Dies würde eine Windows Phone-Anwendung wegen nicht genügend Arbeitsspeicher abstürzen.
Nun möchte ich versuchen "Random Access Datenvirtualisierung". Ich sehe, wie die Schnittstellen implementiert werden IObservableVector<object>, INotifyCollectionChanged
(ja <object>
b / c <T>
funktioniert nicht). Der schwierige Teil ist, wie ich Bilder entsorgen und Bilder laden kann. Das Laden von Bildern ist eine Async-Methode.
Ich glaube außerdem, dass diese Lösung Platzhalter haben sollte, genau wie das MSFT-Dokument sagt: "Ein Beispiel für diese Art von Datenvirtualisierung wird häufig in Fotoanzeige-Apps gesehen. Anstatt den Benutzer darauf warten zu lassen, alle Fotos in einem Album herunterzuladen, muss die App stellt Platzhalterbilder dar. Wenn jedes Bild abgerufen wird, ersetzt die App das Platzhalterelement für dieses Bild durch ein Rendering des tatsächlichen Fotos selbst wenn alle Bilder noch nicht heruntergeladen und angezeigt wurden, kann der Benutzer dennoch mit der Sammlung schwenken und interagieren . "
Wenn Sie sich das MSFT-Beispiel für Platzhalter ansehen, scheint "ContainerContentChanging" ein wichtiger Pfad zu sein. Ich vermute hier, dass es eine Möglichkeit gibt, das Bild innerhalb dieses Ereignisses zu entsorgen und auch das Laden eines Bildes zu starten. Ссылка
Dies wird auf eine Frage herunterkochen - Wo ist es möglich, den Image-Stream zu entfernen und das Laden eines Images für eine Random-Access-Virtualisierungsliste zu starten? Dies ist ein sehr häufiges Szenario in Foto-Apps und ist super einfach in iOS zu machen, aber es scheint noch niemand es unter Windows-Laufzeitumgebung getan zu haben.
Sie müssen die Implementierung von VirtualizingCollection anpassen, überprüfen Sie bitte den folgenden Artikel Ссылка .
Ich habe eine Beispielanwendung mit einer Anpassung von VirtualizingCollection für Windows Phone 8.1 Runtime App geschrieben.
%Vor%Schreiben Sie später den ThumbnailItem-Provider.
%Vor%Anschließend müssen Sie in Ihrem ViewModel eine IList-Eigenschaft erstellen und den Wert mithilfe einer Implementierung von VirtualizingCollection festlegen. Ich schlage vor, dass Sie AsyncVirtualizingCollection verwenden.
%Vor%Schließlich müssen Sie in der Ansicht das DataContext-Objekt mithilfe einer Instanz von ViewModel festlegen, und Ihr ListView sollte ähnlich aussehen:
%Vor%
Natürlich muss die Logik des Anbieters entsprechend Ihren Anforderungen geändert werden, der Code, den ich geschrieben habe, ist nur ein Beispiel.
Bitte markieren Sie es als Antwort, wenn Ihnen geholfen wurde.
Mit freundlichen Grüßen, Denys
BEARBEITEN Friend @Quincy, ich habe ein einfaches Beispiel gepostet, du kannst es anpassen. Vielleicht enthält die ThumbnailItem-Klasse für Ihre Anwendung die Filename-Eigenschaft, die den IsolateStorageFile-Dateinamen angibt. In diesem Fall müssen Sie eine Bindung mit dem Konverter erstellen. Daher müssen Sie ein IValueConverter-Objekt implementieren, um mithilfe der IsolateStorageFile eine BitmapImage-Instanz zu erstellen.
BitmapImage image = neues BitmapImage (); image.SetSource (Quelldatei); Rückbild;
Über das Schließen von Bildern hat die VirtualizingCollection standardmäßig eine Seitengröße von 100 definiert. Ihre IsolateStorageFiles werden einmal verwendet, um die BitmapImage in Ihrem IValueConverter-Objekt zu erstellen. Später wird die VirtualizingCollection alte Seiten löschen, wenn sie nicht verwendet werden (nicht angezeigt, überprüfen Sie die Implementierung von VirtualizingCollection), und schließlich wird der GC das BitmapImage schließen und verwerfen.
Die Portierung von VirtualizingCollection ist einfach, ich erinnere mich, dass ich gerade Änderungen an der AsyncVirtualizingCollection-Klasse vorgenommen habe. Meine Lösung war einfach:
Ersetzen Sie ThreadPool.QueueUserWorkItem für ThreadPool.RunAsync.
Trace für Debug ersetzen (nur Nachrichten debuggen, nicht wirklich wichtig).
Ersetzen Sie den Aufruf von SynchronizationContext-Methoden mit:
(für Windows Phone App) CoreApplication.MainView.CoreWindow.Dispatcher.
(für Windows app) CoreApplication.MainView.Dispatcher.
Ich hoffe, es hilft dir.
Tags und Links c# windows-runtime windows-8.1 windows-phone-8.1