c# windows-runtime windows-phone-8.1 windows-8.1

c# - Virtualización de datos de acceso aleatorio para ListView en Windows Runtime



windows-runtime windows-phone-8.1 (1)

Debe adaptar la implementación de VirtualizingCollection, consulte el siguiente artículo http://www.codeproject.com/Articles/34405/WPF-Data-Virtualization .

Escribí una aplicación de muestra usando una adaptación de VirtualizingCollection para Windows Phone 8.1 Runtime App.

public class ThumbnailItem { public Uri ImageUri { get; set; } }

Luego escribe el proveedor ThumbnailItem.

public class ThumbnailProvider : IItemsProvider<ThumbnailItem> { private readonly int _itemsCount; public ThumbnailProvider(int itemsCount) { _itemsCount = itemsCount; } public int FetchCount() { return _itemsCount; } public IList<ThumbnailItem> FetchRange(int startIndex, int count) { var items = new List<ThumbnailItem>(); while (count-- > 0) { items.Add(new ThumbnailItem() { ImageUri = new Uri("ms-appx:///Assets/Square71x71Logo.scale-240.png") }); } return items; } }

Luego, dentro de su ViewModel, debe crear una propiedad IList y establecer el valor utilizando una implementación de VirtualizingCollection. Sugiero que use AsyncVirtualizingCollection.

Items = new AsyncVirtualizingCollection<ThumbnailItem>(new ThumbnailProvider(1000000), 100);

Finalmente, en la vista debe establecer el objeto DataContext utilizando una instancia de su ViewModel y su ListView debe ser similar a:

<ListView ItemsSource="{Binding Items,Mode=OneWay}" VirtualizingStackPanel.VirtualizationMode="Recycling"> <ListView.ItemsPanel> <ItemsPanelTemplate> <WrapGrid Orientation="Horizontal"/> </ItemsPanelTemplate> </ListView.ItemsPanel> <ListView.ItemTemplate> <DataTemplate> <Grid Margin="0 0 20 20"> <Image Source="{Binding ImageUri,Mode=OneTime}" Width="72" Height="72"/> </Grid> </DataTemplate> </ListView.ItemTemplate>

Por supuesto, la lógica del proveedor debe cambiarse de acuerdo con sus requisitos, el código que escribí es solo una muestra.

Por favor, márcalo como respuesta si te ayudó.

Saludos, Denys

EDITAR Friend @Quincy, publiqué un ejemplo simple, puedes adaptarlo. Tal vez para su aplicación, la clase ThumbnailItem contendrá la propiedad Filename que indica el nombre del archivo IsolateStorageFile. En ese caso, debe crear un Enlace con convertidor, por lo que debe implementar un objeto IValueConverter para crear una instancia de BitmapImage utilizando IsolateStorageFile.

BitmapImage image = new BitmapImage (); image.SetSource (sourceFile); imagen de retorno;

Sobre el cierre de imagen, VirtualizingCollection ha definido un tamaño de página, 100 por defecto. El suyo IsolateStorageFiles se usará una vez para crear BitmapImage en su objeto IValueConverter. Más tarde, VirtualizingCollection eliminará las páginas antiguas si no están en uso (no se muestran, verifique la implementación de VirtualizingCollection), y finalmente el GC cerrará y eliminará la BitmapImage.

Portar VirtualizingCollection es fácil, recuerdo que acabo de hacer cambios en la clase AsyncVirtualizingCollection. Mi solución fue simple:

Reemplace ThreadPool.QueueUserWorkItem para ThreadPool.RunAsync.

Reemplazar rastreo para depurar (solo depurar mensajes, no es realmente importante).

Reemplace la invocación de métodos SynchronizationContext utilizando:

(para la aplicación de Windows Phone) CoreApplication.MainView.CoreWindow.Dispatcher.

(para la aplicación de Windows) CoreApplication.MainView.Dispatcher.

Espero que te ayude.

Estoy implementando una lista que fácilmente podría tener 10,000 imágenes pequeñas. El caso de uso real muestra una lista de miniaturas de un video para que pueda desplazarse por un video cuadro por cuadro. Puse una miniatura del video en la lista cada 2 / 3rds de un segundo en el video. Necesito apoyar videos muy largos (por ejemplo, 1 hora de video).

Entonces las opciones de virtualización:

http://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh780657.aspx

Probé la "virtualización de datos incrementales" y eso consume demasiada memoria porque las imágenes solo se pueden consultar mediante transmisiones y terminaré abriendo 10.000 secuencias. Esto colgaría una aplicación de Windows Phone debido a una falta de memoria.

Ahora me gustaría probar la "virtualización de datos de acceso aleatorio". Veo cómo implementar las interfaces IObservableVector<object>, INotifyCollectionChanged (yes <object> b / c <T> no funciona). La parte difícil es cómo puedo deshacerme de las imágenes y cargarlas. La carga de imágenes es un método Async.

Además, creo que esta solución debe tener marcadores de posición como dice el documento MSFT "Un ejemplo de este tipo de virtualización de datos se ve a menudo en las aplicaciones de visualización de fotos. En lugar de hacer que el usuario espere para descargar todas las fotos de un álbum, la aplicación muestra imágenes de marcador de posición A medida que se recupera cada imagen, la aplicación reemplaza el elemento de marcador de esa imagen con una representación de la foto real. Aunque no se han descargado y visualizado todas las imágenes, el usuario puede seguir e interactuar con la colección ".

Mirando la muestra de MSFT para marcadores de posición, usar "ContainerContentChanging" parece una ruta importante. Supongo que hay una forma de deshacerse de la imagen dentro de este evento y comenzar la carga de una imagen también. https://code.msdn.microsoft.com/windowsapps/ListViewSimple-d5fc27dd

Esto se reduce a una pregunta: ¿dónde es posible deshacerse de la secuencia de imágenes y comenzar la carga de una imagen para una lista de virtualización de acceso aleatorio? Este es un escenario muy común en las aplicaciones de fotos y es muy fácil de hacer en iOS, pero parece que nadie lo ha hecho aún en el tiempo de ejecución de Windows.