Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Yes, it is possible to use images from isolated storage in the app UI. It requires loading the image from the file into the <code>BitmapImage</code> and then binding <code>ImageSource</code> of your control to that <code>BitmapImage</code>. I'm using the following approach:</p> <p>First, there's a method to load image asynchronously:</p> <pre><code>private Task&lt;Stream&gt; LoadImageAsync(string filename) { return Task.Factory.StartNew&lt;Stream&gt;(() =&gt; { 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; }); } </code></pre> <p>Then it can be used like this:</p> <pre><code>public async Task&lt;BitmapSource&gt; FetchImage() { BitmapImage image = null; using (var imageStream = await LoadImageAsync(doc.ImagePath)) { if (imageStream != null) { image = new BitmapImage(); image.SetSource(imageStream); } } return image; } </code></pre> <p>And finally you just assign return value of <code>FetchImage()</code> method to some of your view model's property, to which the UI element is bound. Of course, your view model should properly implement <code>INotifyPropertyChanged</code> interface for this approach to work reliably.</p> <hr> <p>If you want to use attached properties approach, here's how you do it:</p> <pre><code>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(() =&gt; { using (var isoStore = IsolatedStorageFile.GetUserStoreForApplication()) { if (isoStore.FileExists(path)) { var stream = isoStore.OpenFile(path, System.IO.FileMode.Open, FileAccess.Read); uiThread.Post(_ =&gt; { var _img = new BitmapImage(); _img.SetSource(stream); img.Source = _img; }, null); } } }); } } } </code></pre> <p>And then in XAML:</p> <pre><code>&lt;Image local:IsoStoreImageSource.IsoStoreFileName="{Binding Path}" /&gt; </code></pre> <p>Some limitations of this approach:</p> <ul> <li>It only works on <code>Image</code> control, though you can change this to a whichever type you want. It's just not very generic.</li> <li>Performance-wise, it will use a thread from the threadpool every time image source is changed. It's the only way to do asynchronous read from isolated storage on Windows Phone 8 right now. And you definitely don't want to do this synchronously.</li> </ul> <p>But it has one one important advantage:</p> <ul> <li>It works! :)</li> </ul>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload