4

Isolates ストレージに存在するイメージを、xaml を介してイメージ コントロールにバインドすることは可能ですか。プロパティを介して画像を取得し、それを xaml コントロールにバインドするなどの実装をいくつか見つけました。しかし、これは私が探している実装ではありません。私の質問は、アタッチ プロパティとヘルパー メソッドを記述して、分離ストレージからコンテンツをフェッチするようなものです。Windows Phone 7 で使用されている LowProfileImage クラスで同様の実装を見つけましたが、現在は非推奨になっていると思います。誰かが同様の実装を試みた場合は、同じことを達成するのを手伝ってください。また、実装によってパフォーマンスが低下する場合は、その情報についても言及してください。

4

2 に答える 2

10

はい、アプリ UI で分離ストレージの画像を使用できます。ファイルから にイメージをロードしてから、コントロールをBitmapImageそれにバインドする必要があります。私は次のアプローチを使用しています:ImageSourceBitmapImage

まず、画像を非同期でロードする方法があります。

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ますが、これを必要なタイプに変更できます。あまり一般的ではありません。
  • パフォーマンスに関しては、イメージ ソースが変更されるたびに、スレッドプールのスレッドが使用されます。現在、Windows Phone 8 で分離ストレージから非同期読み取りを行う唯一の方法です。そして、これを同期的に実行したくないことは間違いありません。

しかし、これには重要な利点が 1 つあります。

  • できます!:)
于 2013-04-19T11:24:05.543 に答える
1

私は上記のアプローチが好きですが、興味があれば、もっと簡単でハックな方法があります。

xaml に入り、画像ソースを文字列プロパティにバインドしてから、ファイル パスを動的にプロパティに入れることができます。

<!-- XAML CODE -->
 <Image Source="{Binding imagePath}"/>


//Behind property
public String imagePath { get; set; }

パスを画像パスにロードし、画像ソースを画像パス文字列にバインドします。INotifyPropertyChanged を実行する必要があるかもしれませんが、このメソッドは適切なバインドで機能するはずです。

于 2013-04-19T15:18:45.140 に答える