注意:通用Windows平台(也称为Windows 10应用程序,而不是WPF)
我有大约80个图像文件,需要显示在一个页面的列表视图中。当用户返回到上一页时,我需要释放Image控件,以便可以删除这些图像。
问题是直接绑定到图像uri锁定图像文件,并且返回时不会释放它。
我用的是MVVMLight
一些代码:
public class FileNameToFullUriConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
string ori = value.ToString();
string file = ori.Split('/').Last();
string img = file.Split('.')[0] + ".png";
img = "ms-appdata:///local/" + StaticClass.ImageFolder + "/" + img;
return img;
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
return null;
}
}和XAML
<DataTemplate>
<Grid>
<Image x:Name="Image2"
Grid.Column="1"
HorizontalAlignment="Left"
Source="{Binding Page2.Page.file,
Converter={StaticResource FileNameToFullUriConverter},
Mode=OneWay}"
Stretch="UniformToFill" />
</Grid>
</DataTemplate>我试过:
什么是工作的,但不能应用:在ViewModel中,我添加了另一个属性
ObservableCollection<BitmapImage>,然后将ListView绑定到此集合。通过这种方式,所有的映像都将被加载到RAM中,没有锁定文件,但是它会导致一个严重的问题:占用过多的RAM。我的应用程序从使用绑定到URI,通过直接绑定到BitmapImage,占用了大约100 MB内存到900 MB内存。而且,加载到页面所需的时间要长一些,因为它必须在列表呈现完成之前读取所有图像文件并将其加载到RAM中。
那么,如何在Windows 10中处理图像控件呢?
PS:这个图像控制:MSDN中的图像类
发布于 2015-12-22 09:05:00
您可以在页面后面的代码中维护图像控件的列表。当应用程序返回时,您可以为每个图像设置Source属性为null:
<DataTemplate>
<Grid>
<Image Loaded="Image_Loaded" />
</Grid>
</DataTemplate>在代码后面:
private List<Image> _images = new List<Image>();
private void Image_Loaded(object sender, RoutedEventArgs e)
{
_images.Add(sender as Image);
}
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
base.OnNavigatedFrom(e);
foreach(var img in _images)
{
img.Source = null;
}
}所有的锁都会被释放。
发布于 2015-12-21 09:34:19
发布于 2016-08-07 08:24:56
我也有同样的问题。我用了一种解决办法,我不确定这是否是最好的办法。我添加了一个方法来删除已删除的项目,并在每次应用程序启动或列表刷新时调用该方法。
private ObservableCollection<BitmapImage> _items; // your collection which is bound to ListView
// deleting images of removed items
private async Task DeleteUnusedImages()
{
try
{
var folder = await ApplicationData.Current.LocalFolder.GetFolderAsync("folderName");
var files = await folder.GetFilesAsync(); // getting all files inside that folder
foreach (var file in files)
{
// checking if the image still exist in the collection or got removed
// if removed then remove it from the local folder too.
if (!_items.Any(i => i.ImageName.Contains(file.Name)))
{
await file.DeleteAsync(StorageDeleteOption.PermanentDelete);
}
}
}
catch (Exception ex)
{
}
}问题是,当您从绑定到ListView的集合中删除项时,ListView在几次刷新之前不会释放该项。删除一个项目后,我尝试手动删除它,方法是转到应用程序的"LocalState“文件夹,但是它说它被应用程序使用,不能被删除。
https://stackoverflow.com/questions/34392123
复制相似问题