2016-04-29 50 views
1

相對於UWP和XAML而言,我並不確定如何進行調試。帶有網格視圖的UWP應用程序在滾動時丟失圖像

我有一個基於Template10漢堡包模板和Tem​​plate10增量加載示例的UWP應用程序,以及來自示例照片查看器(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。我原本想存儲圖像路徑,但不適用於圖片庫中的任何內容。

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屬性獲取器從StorageItemThumbnail屬性即時返回BitmapImage構建 - 與使用轉換器時相同的問題。

通過在getter中添加一些調試語句,我看到第二個請求上的BitmapImage的高度和寬度爲0. Aha!那麼爲什麼是0?

查看第二個請求上的StorageItemThumbnail屬性,我看到Stream位置在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

您可以嘗試使用編譯結合X:綁定,而不是綁定
在這種情況下,你的應用程序性能比較會更加快捷。

優化您的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:綁定並在稍後的資源字典日期模板中使用它。 問題是Image控件停止顯示它們。 當應用第一次打開時,我的圖像顯示在屏幕上顯示的gridview項目中,當向下滾動時,我看到所有其他圖像。但是 - 如果我向後滾動,在某些時候圖像不再顯示,只有黑色gridview項目和名稱作爲文本框。 – SheriSteeves

+0

這看起來像數據虛擬化問題 –

+0

這是因爲我能夠在Template10增量示例代碼中通過向列表視圖模板添加圖像來重現我的應用程序不良行爲。這就像它不知道它已被視圖卸載,所以它不知道何時重新加載它。我是一個完整的新手,所以我不確定我錯過了什麼,但我正在看你的建議和其他樣本。 – SheriSteeves