我使用AdaptiveGridView将文件夹中的图像列表加载到页面上。我的问题是如何在图像准备就绪后立即加载图像,而不必等待处理整个图像列表。 这是我的代码: C#
"Permission denied (publickey)."
XAML:
public class Images
{
public ImageSource ImageURL { get; set; }
public string ImageText { get; set; }
}
private List<Images> ImageCollection;
private async void Button_Click(object sender, RoutedEventArgs e)
{
ImageCollection = new List<Images>();
// pick a folder
var folderPicker = new Windows.Storage.Pickers.FolderPicker();
folderPicker.FileTypeFilter.Add(".jpg");
var folder = await folderPicker.PickSingleFolderAsync();
var filesList = await folder.CreateFileQueryWithOptions(new QueryOptions(CommonFileQuery.DefaultQuery, new string[] { ".jpg", ".png", ".jpeg" })).GetFilesAsync();
for (int i = 0; i < filesList.Count; i++)
{
StorageFile imagefile = filesList[i];
BitmapImage bitmapimage = new BitmapImage();
using (IRandomAccessStream stream = await imagefile.OpenAsync(FileAccessMode.Read))
{
bitmapimage.SetSource(stream);
}
ImageCollection.Add(new Images()
{
ImageURL = bitmapimage,
ImageText = filesList[i].Name
});
countPhotos.Text = i.ToString() + "out of" + filesList.Count.ToString();
}
AdaptiveGV.ItemsSource = ImageCollection;
}
我厌倦了移动for循环中的<Page.Resources>
<DataTemplate x:Key="PhotosList">
<Grid>
<Image Source="{Binding ImageURL}"
Stretch="UniformToFill"
HorizontalAlignment="Center"
VerticalAlignment="Center">
</Image>
</Grid>
</DataTemplate>
</Page.Resources>
<StackPanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Button HorizontalAlignment="Left" VerticalAlignment="Top" Content="click me" Click="Button_Click">
</Button>
<TextBlock Name="countPhotos">
</TextBlock>
<ScrollViewer>
<UWPToolkit:AdaptiveGridView x:Name="AdaptiveGV"
ItemHeight="300" DesiredWidth="500"
ItemTemplate="{StaticResource PhotosList}">
</UWPToolkit:AdaptiveGridView>
</ScrollViewer>
</StackPanel>
,但这减慢了过程,我不认为这是完成我在这里尝试做的最好的方法。还有其他建议吗?
谢谢
答案 0 :(得分:1)
您应该使用ObservableCollection
代替List
。然后,您可以在添加图像之前将集合分配给ItemsSource
属性。 ObservableCollection
通知用户界面有关更改,例如关于添加的元素。
除此之外,您还应该使用async BitmapImage.SetSourceAsync()
方法。
public class ImageItem
{
public ImageSource Image { get; set; }
public string ImageText { get; set; }
}
private async void Button_Click(object sender, RoutedEventArgs e)
{
var imageCollection = new ObservableCollection<ImageItem>();
AdaptiveGV.ItemsSource = imageCollection;
for ...
{
...
await bitmapimage.SetSourceAsync(stream);
...
imageCollection.Add(new ImageItem()
{
Image = bitmapimage,
ImageText = filesList[i].Name
});
}
}
另请注意,我已将(令人困惑的)名称Images
和ImageURL
替换为
ImageItem
和Image
。您必须将DataTemplate中的Image.Source
绑定更改为:
<Image Source="{Binding Image}"
下一步可能是创建一个视图模型,将ObservableCollection<ImageItem>
保存为(只读)属性:
public class ViewModel
{
public ObservableCollection<ImageItem> ImageCollection { get; }
= new ObservableCollection<ImageItem>();
public async Task LoadImages(StorageFolder folder)
{
var queryOptions = new QueryOptions(
CommonFileQuery.DefaultQuery, new string[] { ".jpg", ".png", ".jpeg" });
var files = await folder.CreateFileQueryWithOptions(queryOptions).GetFilesAsync();
foreach (var file in files)
{
using (var stream = await file.OpenReadAsync())
{
BitmapImage image = new BitmapImage();
await image.SetSourceAsync(stream);
ImageCollection.Add(new ImageItem
{
Image = image,
ImageText = file.Name
});
}
}
}
}
您可以在Page构造函数中将Page的DataContext
分配给视图模型的实例,并在Button Click上调用LoadImages()
方法:
public MainPage()
{
InitializeComponent();
DataContext = new ViewModel();
}
private async void Button_Click(object sender, RoutedEventArgs e)
{
var folderPicker = new Windows.Storage.Pickers.FolderPicker();
folderPicker.FileTypeFilter.Add(".jpg");
var folder = await folderPicker.PickSingleFolderAsync();
if (folder != null)
{
await ((ViewModel)DataContext).LoadImages(folder);
}
}
在XAML中,您可以将ItemsSource属性绑定到ImageCollection属性,如下所示:
<UWPToolkit:AdaptiveGridView ...
ItemsSource="{Binding ImageCollection}"
ItemTemplate="{StaticResource PhotosList}" />