2016-04-29 2 views
1

Скорее новое для UWP и XAML, и я не уверен, как отладить это.Приложение UWP с изображением сетки Потеря изображений при прокрутке

У меня есть приложение UWP на основе шаблона шаблона Template10 и примерный пример загрузки Template10, а также несколько бит из образца для просмотра фотографий (Windows 8: Making a Simple Photo Viewer in C# and XAML).

Я изменил главную страницу, чтобы отобразить Gridview изображений из папки «Изображения», при этом изображения загружаются постепенно. Я также вытащил некоторые из образцов для просмотра фотографий (Windows 8: Making a Simple Photo Viewer in C# and XAML).

Когда приложение запускается, изображения отображаются как ожидалось, и при прокрутке вниз изображения загружаются и отображаются по требованию. Проблема заключается в том, что я просматриваю резервную копию списка, изображения больше не отображаются. Мои элементы gridview все еще там, где указаны имя файла и цветной фон, но изображение больше не отображается.

Чтобы сохранить размер моей памяти небольшим, я не сохраняю фактическое изображение растрового изображения как часть моей коллекции, а вместо этого - StorageItemThumbnail. Я изначально хотел сохранить только путь к изображению, но это ничего не работает в библиотеке Pictures.

public class Picture 
{ 
    public StorageItemThumbnail ImageThumbNail {get; set;} 
    public string Name {get; set;} 
} 

Для отображения этого я использую класс преобразования для создания потока, чтобы установить источник изображения:

public object Convert(object value, Type targetType, object parameter, string language) 
{ 

    BitmapImage image = null; 

    if (value != null) 
    { 
     if (value.GetType() != typeof(StorageItemThumbnail)) 
     { 
      throw new ArgumentException("Expected a StorageItemThumbnail as binding input."); 
     } 
     if (targetType != typeof(ImageSource)) 
     { 
      throw new ArgumentException("Expected ImageSource as binding output."); 
     } 

     if (Windows.ApplicationModel.DesignMode.DesignModeEnabled) 
     { 
      image = new BitmapImage(); 
      image.UriSource = new Uri("ms-appx:///Assets/DesignModeThumbnailPlaceholder.png"); 
     } 
     else 
     { 
      StorageItemThumbnail ThumbNailFile = (StorageItemThumbnail)value; 

      if (ThumbNailFile == null) 
       return image; 

      image = new BitmapImage(); 
      IRandomAccessStream thumbnailStream = ThumbNailFile as IRandomAccessStream; 
      image.SetSource(thumbnailStream); 
     } 

    } 

    return (image); 

} 

И это связано в моем XAML следующим образом:

<DataTemplate x:Name="PictureGridTemplate2"> 
    <Grid Height="150" Width="150"> 
     <Grid.RowDefinitions> 
      <RowDefinition Height="*" /> 
      <RowDefinition Height="Auto" /> 
     </Grid.RowDefinitions> 
     <Border Grid.RowSpan="2" Background="Black" Opacity="0.8" /> 
     <Image Width ="130" HorizontalAlignment="Center" 
       Stretch="Uniform" Source="{Binding ImageThumbNail, Converter={StaticResource ThumbnailFileToImageSourceConverter}}"/> 
     <TextBlock Grid.Row="1" MaxHeight="30" Text="{Binding Name}" 
        Foreground="White" TextTrimming="CharacterEllipsis"/> 
    </Grid> 
</DataTemplate> 

Может ли кто-нибудь указать мне, в каком направлении я ошибался?

Шери

* ПОСТАНОВИЛИ *

я, наконец, удалось выяснить, что является причиной этой проблемы.

Это был побочный эффект виртуализации gridview, моей модели данных и того, как я поставлял изображение через конвертер.

В качестве теста я удалил конвертер, изменил мою модель данных, чтобы сохранить экземпляр BitmapImage миниатюры (меньше, чем сохранение всего изображения) и привязать непосредственно к этому свойству. Это сработало, изображения, отображаемые на экране, когда я прокручивал вверх и вниз по моему gridview.

Затем я изменил свою модель данных, чтобы получить свойство BitmapImage getter вернуть BitmapImage на лету из свойства StorageItemThumbnail - той же проблемы, что и при использовании преобразователя.

Добавив некоторые инструкции для отладки в getter, я увидел, что высота и ширина BitmapImage во втором запросе равны 0. Aha! Так почему же 0?

Посмотрев на свойство StorageItemThumbnail по второму запросу, я увидел, что позиция потока была в EOF (не 0, как в первом запросе) - так это объясняет ширину и высоту 0, что объясняет пустой контроль изображения на экран.

Я изменил свой код, чтобы использовать StorageItemThumbnail.CloneStream, и теперь отображаются все изображения.

Вот метод конвертер Сейчас:

public object Convert(object value, Type targetType, object parameter, string language) 
    { 

     BitmapImage image = null; 

     if (value != null) 
     { 
      if (value.GetType() != typeof(StorageItemThumbnail)) 
      { 
       throw new ArgumentException("Expected a StorageItemThumbnail as binding input."); 
      } 
      if (targetType != typeof(ImageSource)) 
      { 
       throw new ArgumentException("Expected ImageSource as binding output."); 
      } 

      if ((StorageItemThumbnail)value == null) 
      { 
       System.Diagnostics.Debug.WriteLine("Thumbnail is null."); 
       return image; 
      } 

      image = new BitmapImage(); 

      using (var thumbNailClonedStream = ((StorageItemThumbnail)value).CloneStream()) 
      { 
       System.Diagnostics.Debug.WriteLine("Setting image source from cloned stream."); 
       image.SetSource(thumbNailClonedStream); 
      } 
     } 

     return (image); 

    } 

Спасибо всем, кто нашел время, чтобы ответить и помочь мне точку в правильном направлении.

+0

конвертер является причиной. Он звонит каждый раз, когда вы каждый раз прокручиваете создание изображений. Скорее сохраните BitMapImage. – Archana

+0

Я не думаю, что если бы я поставил точку останова в методе Convert, он только попадает один раз для каждого изображения, поскольку они инкрементно загружаются. Когда все будет загружено, я могу прокручивать вверх и вниз столько, сколько хочу, и точка останова не запускается. Вся причина, по которой не сохраняется BitmapImage, заключается в том, чтобы поддерживать низкий уровень памяти. – SheriSteeves

ответ

0

Вы можете попробовать использовать скомпилированы связывание х: Bind вместо связывания
В этом случае приложение Perfomance будет гораздо быстрее.

Оптимизация DataTemplate с фазами, чтобы обновить GridView элементы постепенно:

<Grid Height="150" Width="150"> 
    <Grid.RowDefinitions> 
     <RowDefinition Height="*" /> 
     <RowDefinition Height="Auto" /> 
    </Grid.RowDefinitions> 
    <Border Grid.RowSpan="2" Background="Black" Opacity="0.8" /> 
    <Image Width ="130" HorizontalAlignment="Center" 
      Stretch="Uniform" Source="{Binding ImageThumbNail, Converter={StaticResource ThumbnailFileToImageSourceConverter}}" x:Phase="2"/> 
    <TextBlock Grid.Row="1" MaxHeight="30" Text="{Binding Name}" x:Phase="1" 
       Foreground="White" TextTrimming="CharacterEllipsis"/> 
    </Grid> 

Читать эту темы:
ListView and GridView UI optimization
ListView and GridView data virtualization

+0

Прямо сейчас моя проблема не о скорости; изображения или фактически миниатюры, загружаются довольно быстро. Я посмотрю на x: Связывание и использование этого в шаблоне даты словаря ресурса позже. Проблема в том, что управление изображением перестает их отображать. Когда приложение открывается первым, мои изображения отображаются в элементах сетки, отображаемых на экране, и когда я прокручиваю вниз, я вижу все мои другие изображения. НО - если я прокручиваю резервную копию, в какой-то момент изображения больше не отображаются, а только черный элемент gridview и имя в виде текстового поля. – SheriSteeves

+0

Это похоже на проблему виртуализации данных –

+0

Это так, как я смог воспроизвести плохое поведение моих приложений в инкрементном примере кода Template10, добавив изображение в шаблон его списка. Это похоже на то, что он не знает, что он был выгружен точкой зрения, поэтому он не знает, когда его перезагрузить. Я полный новичок со всем этим, поэтому я не уверен, что я пропустил, но я смотрю ваши предложения и другие образцы. – SheriSteeves

Смежные вопросы