使用图像填充 ListView 时出现内存不足异常 (Windows Phone 8.1)
Out of Memory Exception when Populating ListView with Images (Windows Phone 8.1)
这样我就可以将图片库中自定义文件夹中的图像显示到应用程序中的 ListView 中。但是,当该自定义文件夹有 3 个或更多图像时,要么发生内存不足异常,要么应用程序崩溃并且 Visual Studio 甚至没有意识到应用程序已经崩溃。我的问题是我怎样才能完成这项工作?
这是我的代码...
在xaml.cs文件中:
List<StorageFile> FileList = (await temp.GetFilesAsync()).ToList();
List<ImageItem> ImageList = new List<ImageItem>();
for (int i = 0; i < FileList.Count; i++)
{
using (IRandomAccessStream FileStream = await FileList[i].OpenAsync(FileAccessMode.Read))
{
using(StorageItemThumbnail thumbnail = await file.GetThumbnailAsync(ThumbnailMode.PicturesView))
{
if (thumbnail != null && thumbnail.Type == ThumbnailType.Image)
{
BitmapImage bitmap = new BitmapImage();
await bitmap.SetSourceAsync(FileStream);
ImageList.Add(new ImageItem() { ImageData = bitmap });
}
}
}
}
this.PhotoListView.DataContext = ImageList;
这是我的助手Class:
public class ImageItem
{
public BitmapImage ImageData { get; set; }
}
这是我的 xaml ListView 代码:
<ListView Grid.Column="1"
Grid.Row="0"
x:Name="PhotoListView"
Grid.RowSpan="1"
ItemsSource="{Binding}">
<ListView.ItemTemplate>
<DataTemplate>
<Image Source="{Binding ImageData}"
Margin="10"/>
</DataTemplate>
</ListView.ItemTemplate>
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
</ListView>
您的代码存在问题,当您使用 BitmapImage
时没有指定 DecodePixelHeight
和 DecodePixelWidth
,您可以通过两种方式解决问题:
第一个是指定 DecodePixelHeight
和 DecodePixelWidth
,第二个是使用此代码将图像的路径传递到列表视图:
List<StorageFile> FileList = (await temp.GetFilesAsync()).ToList();
List<string> ImageList = new List<string>();
foreach(var file in FileList)
{
ImageList.Add(file.Path);
}
this.PhotoListView.DataContext = ImageList;
Image 控件能够为您完成所有工作,并负责内存管理。
我认为您的主要问题是将 ItemsPanelTemplate
设置为 Stackpanel
。这会扼杀虚拟化。您没有理由覆盖默认项目面板。
此外,正如 frenk91 提到的,将 DecodePixelHeight
和 DecodePixelWidth
添加到您的 XAML 可能会有用。
这样我就可以将图片库中自定义文件夹中的图像显示到应用程序中的 ListView 中。但是,当该自定义文件夹有 3 个或更多图像时,要么发生内存不足异常,要么应用程序崩溃并且 Visual Studio 甚至没有意识到应用程序已经崩溃。我的问题是我怎样才能完成这项工作?
这是我的代码...
在xaml.cs文件中:
List<StorageFile> FileList = (await temp.GetFilesAsync()).ToList();
List<ImageItem> ImageList = new List<ImageItem>();
for (int i = 0; i < FileList.Count; i++)
{
using (IRandomAccessStream FileStream = await FileList[i].OpenAsync(FileAccessMode.Read))
{
using(StorageItemThumbnail thumbnail = await file.GetThumbnailAsync(ThumbnailMode.PicturesView))
{
if (thumbnail != null && thumbnail.Type == ThumbnailType.Image)
{
BitmapImage bitmap = new BitmapImage();
await bitmap.SetSourceAsync(FileStream);
ImageList.Add(new ImageItem() { ImageData = bitmap });
}
}
}
}
this.PhotoListView.DataContext = ImageList;
这是我的助手Class:
public class ImageItem
{
public BitmapImage ImageData { get; set; }
}
这是我的 xaml ListView 代码:
<ListView Grid.Column="1"
Grid.Row="0"
x:Name="PhotoListView"
Grid.RowSpan="1"
ItemsSource="{Binding}">
<ListView.ItemTemplate>
<DataTemplate>
<Image Source="{Binding ImageData}"
Margin="10"/>
</DataTemplate>
</ListView.ItemTemplate>
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
</ListView>
您的代码存在问题,当您使用 BitmapImage
时没有指定 DecodePixelHeight
和 DecodePixelWidth
,您可以通过两种方式解决问题:
第一个是指定 DecodePixelHeight
和 DecodePixelWidth
,第二个是使用此代码将图像的路径传递到列表视图:
List<StorageFile> FileList = (await temp.GetFilesAsync()).ToList();
List<string> ImageList = new List<string>();
foreach(var file in FileList)
{
ImageList.Add(file.Path);
}
this.PhotoListView.DataContext = ImageList;
Image 控件能够为您完成所有工作,并负责内存管理。
我认为您的主要问题是将 ItemsPanelTemplate
设置为 Stackpanel
。这会扼杀虚拟化。您没有理由覆盖默认项目面板。
此外,正如 frenk91 提到的,将 DecodePixelHeight
和 DecodePixelWidth
添加到您的 XAML 可能会有用。