Привязка изображений из изолированного хранилища?

#silverlight #windows-phone-7 #binding

#silverlight #windows-phone-7 #привязка

Вопрос:

Мне нужна помощь, чтобы выяснить, почему два разных способа привязки изображения в XAML ведут себя по-разному.

Вот мой код:

 public class Picture 
    {

        public int ID
        {
            get;
            set;
        }

public string ThumbURL
        {
            get
            {
                return String.Format("http://"  App.ServerAdress  "/Pictures/thumbs/{0}.jpg", ID);
            }

        }

        public int ThumbLocal
        {
           get { return ID; }
        }
}

public class ByteImageConverter : IValueConverter
    {

           public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {


            using (var store =
               IsolatedStorageFile.GetUserStoreForApplication())
            {


                if (!store.FileExists(value)) return null;

                var stream =
                    store.OpenFile(path, FileMode.Open);

                try
                {
                    var image = new BitmapImage();
                    image.SetSource(stream);
                    return image;
                }
                finally
                {
                    stream.Dispose();
                }
            }

        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
  

В случае, если я привязываю изображение таким образом, оно работает:

 <Image  Width="110" CacheMode="BitmapCache" Source="{Binding ThumbURL}" 
                                    Margin="12,0,9,0"/>
  

Но этот способ не:

 <Image  Width="110" CacheMode="BitmapCache" Source="{Binding ThumbLocal,  Mode=TwoWay, Converter={StaticResource imgConverter}}"  
                                        Margin="12,0,9,0"/>
  

Такая ситуация возникает, когда я пытаюсь установить изображение из одного элемента панорамы в другой. В моем случае я хочу добавить изображение из одного списка в другой, и когда я использую первый тип привязки, все работает нормально. Также это работает, когда я перехожу на другую страницу и возвращаюсь назад, появляется изображение. Меня немного смущает такое поведение.

Есть идеи, как я могу решить эту проблему?

Наконец-то я понял, почему это произошло. Перед привязкой я должен загрузить изображение из Интернета и сохранить его в изолированном хранилище, весь этот процесс выполняется асинхронно. И во время, когда я привязываю изображение, там еще нет изображения. Я попытался привязать существующее изображение из изолированного хранилища, и оно отображается правильно. Итак, теперь мне нужно что-то вроде INotifyPropertyChanged . Могу ли я каким-либо образом это сделать, если использую IValueConverter ?

Комментарии:

1. Где на самом деле происходит сбой? Существует множество мест, где ваш код может дать сбой. * Свойство ThumbLocal может отсутствовать в источнике привязки (кстати, вам не нужен Mode = TwoWay) — тогда вам следует проверить свой источник привязки. * Для параметра ThumbLocal может не быть задан путь к файлу, существующему в isostore — вам нужно будет проверить, существует он или нет. * Я не вижу, как переменная типа value — a object используется в FileExists, которая ожидает строку, но я предполагаю, что вы имели в виду преобразовать ее в строку path. * Может произойти сбой OpenFile, и вы, похоже, не пытаетесь его перехватить. * Растровое изображение. Сбой декодирования?

2. У меня тот же вопрос: «Где на самом деле происходит сбой?». Оба кода «рабочие», первый такой, как мне нужно, второй — нет. Я знаю, что мой английский не настолько хорош, но попробуйте прочитать еще раз мой вопрос. Как вы решите этот вариант использования, когда вам нужно привязать изображение из изолированного хранилища, но сначала вы должны загрузить это изображение и сохранить туда (в изолированное хранилище)? Вы были правы насчет FileExists, я немного изменил код, в оригинале я строю путь со строкой. Формат(«{0}», ИДЕНТИФИКАТОР). Я думаю, это происходит потому, что я загружаю изображение и сохраняю в асинхронном режиме, поэтому привязка не видит изображение.

3. Я все еще не знаю, что вы подразумеваете под «не работает». Происходит сбой или изображение просто не отображается? Вы пробовали пошагово просматривать конвертер в отладчике, чтобы посмотреть, вызывалось ли «return image»?

4. Я отредактировал свой вопрос, пожалуйста, прочтите его еще раз.

Ответ №1:

Вы можете сделать так, чтобы, если изображения нет в изолированном хранилище — вы начинали загрузку изображения, но возвращали новое растровое изображение немедленно и только по завершении загрузки — сохраняли изображение в isostore и устанавливали его в качестве источника растрового изображения.

Что-то вроде:

 if (!store.FileExists(value))
{
    var image = new BitmapImage();
    ImageDownloadAndCachingHelper.DownloadImage(path, (s, e) => image.SetSource(e.ImageStream));
    return image;
}
  

Вам нужно реализовать код, который преобразует локальный путь в веб-URI, загрузить его и вызвать обработчик событий, где ImageDownloadedEventArgs содержит ImageStream.

Комментарии:

1. Здравствуйте, ваше решение в порядке, но я не настолько хорош, чтобы его реализовать. Поскольку все это выполняется асинхронно для загрузки и сохранения в изолированном хранилище. Если у вас есть время, вы можете опубликовать остальную часть решения в своем ответе. В любом случае, вы подаете мне идею сделать это таким образом; if (!store.FileExists(path)) return String.Format("http://" App.ServerAdress "/Pictures/thumbs/{0}.jpg", value); Спасибо за помощь.

2. Ваше решение будет работать для получения изображения с веб-адреса, когда его нет в изолированном хранилище. Если вы хотите сохранить его в изолированном хранилище, которого там еще нет, вам придется реализовать какое-либо решение для кэширования, а это слишком нестандартно, чтобы кто-то другой делал это за вас, поскольку это действительно зависит от того, почему вы хотите, чтобы эти изображения находились в изолированном хранилище. Если вы просто используете URI — возможно, веб-стек в любом случае автоматически кэширует его для вас.