在我的应用程序中,我使用下面提到的帮助方法将我的独立存储图像绑定到Image控件。我从链接“Binding Image stored in the Isolated Storage to Image Control in Windows Phone”
获得了这个帮助方法public class IsoStoreImageSource : DependencyObject
{
public static void SetIsoStoreFileName(UIElement element, string value)
{
element.SetValue(IsoStoreFileNameProperty, value);
}
public static string GetIsoStoreFileName(UIElement element)
{
return (string)element.GetValue(IsoStoreFileNameProperty);
}
// Using a DependencyProperty as the backing store for IsoStoreFileName. This enables animation, styling, binding, etc...
public static readonly DependencyProperty IsoStoreFileNameProperty =
DependencyProperty.RegisterAttached("IsoStoreFileName", typeof(string), typeof(IsoStoreImageSource), new PropertyMetadata("", Changed));
private static void Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
Image img = d as Image;
if (img != null)
{
var path = e.NewValue as string;
SynchronizationContext uiThread = SynchronizationContext.Current;
Task.Factory.StartNew(() =>
{
using (var isoStore = IsolatedStorageFile.GetUserStoreForApplication())
{
if (isoStore.FileExists(path))
{
var stream = isoStore.OpenFile(path, System.IO.FileMode.Open, FileAccess.Read);
uiThread.Post(_ =>
{
var _img = new BitmapImage();
_img.SetSource(stream);
img.Source = _img;
}, null);
}
}
});
}
}
}
我在ListBox控件中使用它。如果尝试使用默认库图像,一切都将按预期工作。但是,如果我尝试使用大尺寸的图像(通过设备相机拍摄),应用程序会崩溃。
这是我得到的例外
System.Windows.ni.dll中出现“System.OutOfMemoryException”类型的异常,但未在用户代码中处理
堆栈跟踪
at MS.Internal.FrameworkCallbacks.NotifyManagedDebuggerOnNativeOOM() 在MS.Internal.XcpImports.BitmapSource_SetSource(BitmapSource bitmapSource,CValue& byteStream) 在System.Windows.Media.Imaging.BitmapSource.SetSourceInternal(Stream streamSource) 在System.Windows.Media.Imaging.BitmapImage.SetSourceInternal(Stream streamSource) 在System.Windows.Media.Imaging.BitmapSource.SetSource(Stream streamSource) 在MyaPP.Common.IsoStoreImageSource。<> c__DisplayClass4。<> c__DisplayClass6.b__1(Object _)
答案 0 :(得分:0)
ListBox
内的缓存可能会占用您的记忆,这对于较大的图像尤其明显。我不熟悉您发布的辅助方法,但尝试添加此方法。
if (img != null)
{
BitmapImage bitmapImage = img.Source as BitmapImage;
bitmapImage.UriSource = null;
img.Source = null;
//rest of the code ...
}
答案 1 :(得分:0)
好的,我花了一些时间才回到这个问题。我会在这里分享我的发现,但我不认为它们是对这个问题的真正答案,而是一种解决方法。但是,我希望它会对某人有所帮助。
首先,我想确认OutOfMemoryException
在某些情况下发生。但是,令人惊讶的是,它取决于您正在使用的页面布局。实际上,如果您的布局涉及StackPanel
,则会有例外情况。我想,归结为在MeasureOverride
中如何实现ArrangeOverride
和StackPanel
方法(尽管我在这里可能完全错误)。看起来当ListBox
是StackPanel
的子项时,它会尝试在显示之前加载所有图像。当然,这会导致内存泄漏。
另一方面,如果你使用Grid
之类的东西作为图像列表的父级,那么就没有这样的例外,并且内存负载是合理的。
这是适用于我的页面布局:
<Grid>
<ListBox ItemsSource="{Binding IsoStorePics}">
<ListBox.ItemTemplate>
<DataTemplate>
<Image local:IsoStoreImageSource.IsoStoreFileName="{Binding Path}" Margin="5"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
这是我现在给你的最佳答案。如果有帮助,请告诉我。
答案 2 :(得分:0)
您可以尝试这样,Stream对象将自动处理。
using (IsolatedStorageFile iso = IsolatedStorageFile.GetUserStoreForApplication())
{
if (iso.FileExists(imagePath))
{
using (Stream imagestream = new IsolatedStorageFileStream(imagePath, FileMode.Open, FileAccess.Read, FileShare.Read, iso))
{
BitmapImage bmp = new BitmapImage();
bmp.SetSource(imagestream);
imgControl.Source = bmp;
}
}
}