问题
I have a Windows 8.1 XAML app where I'd like to preload images before navigating between pages.
The naive code I have now is:
// Page1.xaml.cs
private void Button_Click(object sender, RoutedEventArgs e)
{
Frame.Navigate(typeof(Page2));
}
And on the second page:
// Page2.xaml.cs
this.image1.Source = new BitmapImage(new Uri("ms-appx:///Assets/image1.jpg"));
this.image2.Source = new BitmapImage(new Uri("ms-appx:///Assets/image2.jpg"));
Now, when I click the button to navigate, I can see the images being loaded and showing up one at the time. I would like to pre-load the images on the button click and only navigate after the images have been loaded.
Unfortunately, just creating the BitmapImage
objects and waiting for the ImageOpened
events doesn't work. It appears that the images aren't loaded if they aren't rendered to the screen.
Is there a way to force loading of the images from code without adding them to the visual tree?
(Note: a workaround would be to actually add all the images to the Window in some invisible way, but I'd like to avoid that if at all possible)
Final solution:
This is what I've come up with using SetSourceAsync
, as suggested by Filip Skakun:
// Page1.xaml.cs
private async void Button_Click(object sender, RoutedEventArgs e)
{
bitmapImage1 = new BitmapImage();
bitmapImage2 = new BitmapImage();
// Load both images in parallel
var task1 = loadImageAsync(bitmapImage1, "image1.jpg");
var task2 = loadImageAsync(bitmapImage2, "image2.jpg");
await Task.WhenAll(task1, task2);
Frame.Navigate(typeof(Page2));
}
private Task loadImageAsync(BitmapImage bitmapImage, string path)
{
var filePath = ApplicationData.Current.LocalFolder.Path + "\\" + path;
var file = await StorageFile.GetFileFromPathAsync(filePath);
var stream = await file.OpenAsync(FileAccessMode.Read);
await bitmapImage.SetSourceAsync(stream);
}
// Page2.xaml.cs
this.image1.Source = bitmapImage1;
this.image2.Source = bitmapImage2;
回答1:
WinRT XAML Toolkit's AlternativeFrame control and AlternativePage one have a ShouldWaitForImagesToLoad
property that when you set to true and navigate to a page - will only display the page when the images have loaded. AlternativePage
has a Preload()
method you can also override to add more things to await before displaying the page. The way it is implemented though is the page is first added to an invisible container in the visual tree, so loading of those BitmapImages
gets triggered.
Another option might be to use SetSourceAsync() which you can await and I think it starts loading before you use the BitmapImage
in the UI, but then you need to download the file yourself.
来源:https://stackoverflow.com/questions/22771675/winrt-preload-images