将独立存储中存储的图像绑定到Windows Phone中的图像控件 [英] Binding Image stored in the Isolated Storage to Image Control in Windows Phone

查看:24
本文介绍了将独立存储中存储的图像绑定到Windows Phone中的图像控件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以通过xaml将Isolates存储中存在的图像绑定到图像控制.我发现了一些实现,比如通过属性获取图像并将其绑定到 xaml 控件中.但这不是我正在寻找的实现.我的问题是,编写一个附加属性和辅助方法来从独立存储中获取内容.我在 Windows Phone 7 中使用的 LowProfileImage 类中发现了类似的实现.但我认为它现在已被弃用.如果有人尝试过类似的实现,请帮助我实现相同的目标.此外,如果实施有任何性能消耗,请也提及该信息.

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.

推荐答案

是的,可以在应用 UI 中使用来自独立存储的图像.它需要将文件中的图像加载到 BitmapImage 中,然后将控件的 ImageSource 绑定到该 BitmapImage.我正在使用以下方法:

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;
        });
    }

那么就可以这样使用:

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 接口,以便此方法可靠地工作.

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);
                    }
                }
            });               
        }
    }
}

然后在 XAML 中:

And then in XAML:

<Image local:IsoStoreImageSource.IsoStoreFileName="{Binding Path}" />

这种方法的一些限制:

  • 它仅适用于 Image 控件,但您可以将其更改为您想要的任何类型.它只是不太通用.
  • 在性能方面,每次更改图像源时,它将使用线程池中的一个线程.这是目前在 Windows Phone 8 上从独立存储进行异步读取的唯一方法.而且您绝对不想同步执行此操作.
  • It only works on Image control, though you can change this to a whichever type you want. It's just not very generic.
  • 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.

但它有一个重要的优势:

But it has one one important advantage:

  • 它有效!:)

这篇关于将独立存储中存储的图像绑定到Windows Phone中的图像控件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆