是否可能通过xaml将隔离存储中存在的图像绑定到图像控件?我发现一些实现方式,例如通过属性获取图像并将其绑定到xaml控件。但这不是我正在寻找的实现方式。我的问题是,编写一个附加属性和助手方法从隔离存储中获取内容。我在Windows Phone 7中使用的LowProfileImage类中找到了类似的实现方式。但我认为它现在已经过时了。如果有人尝试过类似的实现方式,请帮助我实现相同的功能。此外,如果实现方式有任何性能损耗,请也提供相关信息。
是否可能通过xaml将隔离存储中存在的图像绑定到图像控件?我发现一些实现方式,例如通过属性获取图像并将其绑定到xaml控件。但这不是我正在寻找的实现方式。我的问题是,编写一个附加属性和助手方法从隔离存储中获取内容。我在Windows Phone 7中使用的LowProfileImage类中找到了类似的实现方式。但我认为它现在已经过时了。如果有人尝试过类似的实现方式,请帮助我实现相同的功能。此外,如果实现方式有任何性能损耗,请也提供相关信息。
是的,可以在应用程序UI中使用来自隔离存储的图像。需要将文件中的图像加载到 BitmapImage
中,然后将您控件的 ImageSource
绑定到该 BitmapImage
。 我正在使用以下方法:
首先,有一种异步加载图像的方法:
private Task<Stream> LoadImageAsync(string filename)
{
return Task.Factory.StartNew<Stream>(() =>
{
if (filename == null)
{
throw new ArgumentException("one of parameters is null");
}
Stream stream = null;
using (var isoStore = IsolatedStorageFile.GetUserStoreForApplication())
{
if (isoStore.FileExists(filename))
{
stream = isoStore.OpenFile(filename, System.IO.FileMode.Open, FileAccess.Read);
}
}
return stream;
});
}
那么它可以像这样使用:
public async Task<BitmapSource> FetchImage()
{
BitmapImage image = null;
using (var imageStream = await LoadImageAsync(doc.ImagePath))
{
if (imageStream != null)
{
image = new BitmapImage();
image.SetSource(imageStream);
}
}
return image;
}
最后,你只需将 FetchImage()
方法的返回值分配给某个绑定到 UI 元素的视图模型属性即可。当然,为了使这种方法可靠地工作,你的视图模型应正确实现 INotifyPropertyChanged
接口。
如果您想使用附加属性方法,下面是操作步骤:
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);
}
}
});
}
}
}
然后在XAML中:
<Image local:IsoStoreImageSource.IsoStoreFileName="{Binding Path}" />
这种方法存在一些限制:
Image
控件上使用,尽管您可以将其更改为任何类型。 它只是不是很通用。但它有一个重要的优点:
<!-- XAML CODE -->
<Image Source="{Binding imagePath}"/>
//Behind property
public String imagePath { get; set; }
Deployment.Current.Dispatcher.BeginInvoke()
也可以。主要的区别在于代码的可移植性。System.Threading.SynchronizationContext
是所有.NET环境的通用概念。这意味着,在Windows Store和Windows Phone 8应用程序上它可以同样地工作,而Deployment.Current.Dispatcher
仅适用于Windows Phone。当然,IsolatedStorageFile
也是Windows Phone特定的,因此在这种情况下这两种方法之间的差异并不那么重要。但是,还是有必要牢记这些差异,以备不时之需。 - Haspemulator