1

这个问题在某些方面与这个问题相似:

Windows 8 XAML:通过数据绑定在 GridView 中显示图像列表

我按照其中列出的说明将图像加载到我自己的 GridView 中,我从加载许多图像到仅加载第一个图像,仅此而已;其余的甚至不会显示为空白,而在没有完全加载之前它们都会在那里。这是我的代码,它使用了与上述问题中的大部分内容相同的内容:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.Storage;
using Windows.UI.Xaml.Media.Imaging;
using Windows.Storage.Streams;

namespace present50_2
{
    public class SlideData
    {
        // slide collection that will be used to populate app slides page
        public List<Slide> Slides = new List<Slide>();

        // image files that will be asynchronously loaded
        public IReadOnlyList<StorageFile> files;

        public SlideData(IReadOnlyList<StorageFile> files)
        {
            this.files = files;
        }

        public async void loadSlides()
        {
            int counter = 1;
            Slides = new List<Slide>();

            foreach (var file in files)
            {
                using (var stream = await file.OpenAsync(FileAccessMode.Read))
                {
                    Slides.Add(new Slide(stream, counter.ToString()));
                }

                counter++;
            }
        }

        public class Slide
        {
            public Slide()
            {

            }

            public Slide(IRandomAccessStream stream, string name)
            {
                BitmapImage bmp = new BitmapImage();
                bmp.SetSource(stream);
                Image = bmp;
                this.Title = name;
            }

            /*
            public async void LoadImage()
            {
                IRandomAccessStream fileStream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read);
                BitmapImage bi = new BitmapImage();
                bi.SetSource(fileStream);
                this.Image = bi;
            } */

            public string Title { set; get; }
            public BitmapImage Image { set; get; }
        }
    }
}

该类保存将绑定到网格的数据。这是调用所述类的代码:

protected async override void LoadState(Object navigationParameter, Dictionary<String, Object> pageState)
        {
            var folderPicker = new FolderPicker();
            folderPicker.SuggestedStartLocation = PickerLocationId.DocumentsLibrary;
            folderPicker.FileTypeFilter.Add(".png");
            StorageFolder folder = await folderPicker.PickSingleFolderAsync();

            if (folder != null)
            {
                IReadOnlyList<StorageFile> files = await folder.GetFilesAsync();
                SlideData slides = new SlideData(files);
                slides.loadSlides();
                this.DefaultViewModel["Items"] = slides.Slides;
            }
        }

我将以下 XAML 用于实际的网格布局和绑定:

<!-- Grid-appropriate 125 pixel square item template as seen in the GroupedItemsPage and ItemsPage -->
    <DataTemplate x:Key="Standard125x125ItemTemplate">
        <Grid HorizontalAlignment="Left" Width="125" Height="125">
            <Border Background="{StaticResource ListViewItemPlaceholderBackgroundThemeBrush}">
                <Image Source="{Binding Image}" Stretch="UniformToFill" AutomationProperties.Name="{Binding Title}"/>
            </Border>
            <StackPanel VerticalAlignment="Bottom" Background="{StaticResource ListViewItemOverlayBackgroundThemeBrush}">
                <TextBlock Text="{Binding Title}" Foreground="{StaticResource ListViewItemOverlayForegroundThemeBrush}" Style="{StaticResource TitleTextStyle}" Height="30" Margin="7,0,7,0"/>
            </StackPanel>
        </Grid>
    </DataTemplate>

该代码只是对 StandardStyles.xaml 中的 250x250 模板的修改。

最初,我根本无法在屏幕上加载任何图像(它们只是显示为灰色方块)。然后通过我在这里看到的实现(Kiwi 示例),我能够加载一些图像,但大多数仍然保持灰色:

http://social.msdn.microsoft.com/Forums/windowsapps/en-US/252d4d14-1db3-4f04-93b6-d2eab2c386bc/c-metro-displaying-images-in-a-listview-or-gridview

然后,使用我在上面发布的最后一个解决方案,我只能显示第一张幻灯片,但其他幻灯片都没有显示为灰色框,更不用说加载了。帮助将不胜感激!

4

1 回答 1

0

一点背景

首先,让我们看一下LoadState函数中的这一行:

slides.loadSlides();

上面的方式目前是这样写的,调用loadSlides开始执行。由于它是一个异步方法,因此它与后面的代码并行执行:

this.DefaultViewModel["Items"] = slides.Slides;
...

发生的事情是网格在方法完成之前loadSlides被绑定到集合。这就是您可能只能看到一两张图片的原因。

解决方案

要解决此问题,您必须修复调用loadSlides函数的方式。首先,将函数签名从 更改voidTask

public async Task loadSlides() { ... }

接下来,您需要await调用loadSlides. 当您await使用异步方法时,您实际上是在等待该方法完成后再继续执行。请注意,只有返回Task(或 的某些变体Task<..>)的方法可以是awaited. 添加 后await,页面LoadState函数中的代码应如下所示:

...
SlideData slides = new SlideData(files);
await slides.loadSlides();
this.DefaultViewModel["Items"] = slides.Slides;
...

现在,当loadSlides被调用时,您的程序将一直等到它完成。然后将调用下一行,它将您的网格绑定到完整的幻灯片数据。这应该允许您查看所有图像。

于 2013-08-29T18:50:49.763 回答