Is it possible to bind the image present in the Isolates storage to image control through xaml. I found some implementations like getting the image through the property and binding that into xaml control. But this is not the implementation what I am searching for. My question is like, writing an attach property and helper method to fetch the content from Isolated storage. I found a similar implementation in LowProfileImage class, used in windows phone 7. But I think it is deprecated now. If anyone tried similar implementations please help me to achieve the same. Also if implementation have any performance drains please mention that info too.
Yes, it is possible to use images from isolated storage in the app UI. It requires loading the image from the file into the BitmapImage
and then binding ImageSource
of your control to that BitmapImage
. I'm using the following approach:
First, there's a method to load image asynchronously:
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;
});
}
Then it can be used like this:
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;
}
And finally you just assign return value of FetchImage()
method to some of your view model's property, to which the UI element is bound. Of course, your view model should properly implement INotifyPropertyChanged
interface for this approach to work reliably.
If you want to use attached properties approach, here's how you do it:
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);
}
}
});
}
}
}
And then in XAML:
<Image local:IsoStoreImageSource.IsoStoreFileName="{Binding Path}" />
Some limitations of this approach:
Image
control, though you can change this to a whichever type you want. It's just not very generic.But it has one one important advantage:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With