网格视图的UWP应用程序滚动时丢失图像

时间:2016-04-29 13:34:14

标签: win-universal-app template10

UWP和XAML的新手,我不知道如何调试它。

我有一个基于Template10汉堡包模板和Tem​​plate10增量加载样本的UWP应用程序,以及样本照片查看器中的一些位(Windows 8: Making a Simple Photo Viewer in C# and XAML)。

我修改了主页面,以显示图片文件夹中图像的网格视图,图像以递增方式加载。我还从示例照片查看器(Windows 8: Making a Simple Photo Viewer in C# and XAML)中提取了一些内容。

当应用程序启动时,图像会按预期显示,当我向下滚动时,图像会按需加载和显示。问题是当我向上滚动列表时,图像不再显示。我的gridview项目仍然显示文件名和彩色项目背景,但不再绘制图像。

为了减少内存占用,我不是将实际的Bitmap图像存储为我的集合的一部分,而是存储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实例(小于存储整个图像)并直接绑定到该属性。这很有效,当我在网格视图中上下滚动时,屏幕上显示的图像。

然后我改变了我的数据模型,让BitmapImage属性getter从StorageItemThumbnail属性中动态返回BitmapImage构建 - 与使用转换器时相同。

通过在getter中添加一些调试语句,我看到第二个请求中BitmapImage的高度和宽度为0.啊哈!那么为什么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);

    }

感谢所有花时间回答并帮助我指明正确方向的人。

1 个答案:

答案 0 :(得分: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