How ro store image locally once it was downloaded

2019-06-10 01:40发布

问题:

My Windows Store (aka Windows 8) application uses the default Grid Application template to show the items. The item template there includes an image with overlaid text information. To diminish the size of application I do not store the images for every item, instead I save an Uri with absolute path (http) to the webserver where the image resides. I modified the standard template to bind to the image Uri (I had to convert the Uri to string for this to work properly) and now whenever I start the application all the images are downloaded and shown automatically by the Image control.

What I now want is to automatically save the images which were once downloaded and modify the Uris of the downloaded images to those pointing to the local storage. Here I bump into two problems:

  • I can't get the ImageOpened event to fire if I bind the complete ItemTemplate from the StandardStyles.xaml

This is the binding from my GroupedItemsPage.xaml:

    <GridView
        x:Name="itemGridView"
        ItemTemplate="{StaticResource Standard250x250ItemTemplate}">

The bound template was modified to fire an event (StandardStyles.xaml):

<DataTemplate x:Key="Standard250x250ItemTemplate">
            <Image Source="{Binding ImageUri}" ImageOpened="Image_ImageOpened"/>
</DataTemplate>

The Image_ImageOpened event handler is defined in the code-behind file (`GroupedItemsPage.xaml.cs'), but never fires:

    private void Image_ImageOpened(object sender, RoutedEventArgs e)
    {

    }
  • I don't know how to store the content of the Image framework element as a binary file.

回答1:

I also had to copy some http images locally; here is my working code. You should call this method with internetURI = "http://wherever-your-image-file-is" and a unique name for the image. It will copy the image to AppData's LocalFolder storage, and then it returns the path to the new local image which you can use for your binding. Hope this helps!

    /// <summary>
    /// Copies an image from the internet (http protocol) locally to the AppData LocalFolder.  This is used by some methods 
    /// (like the SecondaryTile constructor) that do not support referencing images over http but can reference them using 
    /// the ms-appdata protocol.  
    /// </summary>
    /// <param name="internetUri">The path (URI) to the image on the internet</param>
    /// <param name="uniqueName">A unique name for the local file</param>
    /// <returns>Path to the image that has been copied locally</returns>
    private async Task<Uri> GetLocalImageAsync(string internetUri, string uniqueName)
    {
        if (string.IsNullOrEmpty(internetUri))
        {
            return null;
        }

        using (var response = await HttpWebRequest.CreateHttp(internetUri).GetResponseAsync())
        {
            using (var stream = response.GetResponseStream())
            {
                var desiredName = string.Format("{0}.jpg", uniqueName);
                var file = await ApplicationData.Current.LocalFolder.CreateFileAsync(desiredName, CreationCollisionOption.ReplaceExisting);

                using (var filestream = await file.OpenStreamForWriteAsync())
                {
                    await stream.CopyToAsync(filestream);
                    return new Uri(string.Format("ms-appdata:///local/{0}.jpg", uniqueName), UriKind.Absolute);
                }
            }
        }
    }