将图像绑定到GridView Windows 8
本文关键字:Windows GridView 图像 绑定 | 更新日期: 2023-09-27 18:29:21
这个问题在某些方面与这个问题类似:
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
然后,使用我在上面发布的最后一个解决方案,我只看到了第一张幻灯片,但其他幻灯片都没有显示为灰色框,更不用说加载了。非常感谢您的帮助!
小背景
首先,让我们看看LoadState
函数中的这一行:
slides.loadSlides();
按照当前编写上述内容的方式,开始执行对loadSlides
的调用。由于它是一个异步方法,它与后面的代码并行执行:
this.DefaultViewModel["Items"] = slides.Slides;
...
发生的情况是,在loadSlides
方法完成之前,网格被绑定到集合。这就是你可能只看到一两张图片的原因。
解决方案
要解决此问题,必须修复调用loadSlides
函数的方式。首先,将函数签名从void
更改为Task
:
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
时,您的程序将等待,直到它完成。然后将调用下一行,它将把您的网格绑定到完整的幻灯片数据。这应该可以让你看到所有的图像。