[深刻淺出Windows 10]應用實戰:Bing在線壁紙

    本章介紹一個使用Bing搜索引擎背景圖接口實現的一個應用——Bing在線壁紙,講解如何使用網絡的接口來實現一個壁紙下載,壁紙列表展現和網絡請求封裝的內容。經過該例子咱們能夠學習到如何使用網絡編程的知識和開放的接口來實現一些有趣的應用程序,如何在項目中封裝相關的功能模塊,從而進一步地瞭解Windows 10應用程序開發的過程。html

23.1 應用實現的功能

    微軟的Bing搜索引擎天天都會挑選出一張圖片做爲今天的主題,而且會對圖片的含義或者圖片所表明的意思進行一番解說,天天的圖片和故事都不同,而且有時候不一樣國家挑選的圖片和故事也不同。你在網頁上打開Bing搜索的中國區主頁(http://cn.bing.com/)那麼就能夠看到今天的bing壁紙的內容和故事,天天都給用戶帶來有內涵有深度的圖片和故事。在桌面的瀏覽器看到的Bing壁紙會很大,除此以外Bing也有手機的版本,對於手機版本Bing也是適配和符合手機分辨率的壁紙大小。編程

    接下來咱們要實現的Bing在線壁紙的應用程序是使用了微軟的Bing壁紙獲取的接口,把Bing搜索引擎天天的壁紙和故事經過網絡接口來獲取,而後在應用程序中顯示出來。由於Bing壁紙天天都是不同的,因此咱們要實現的應用可讓用戶不只僅能夠看到今天的壁紙和故事,也能夠獲取到之前的壁紙和故事。在Bing在線壁紙應用裏面主要實現了兩個功能,一個是顯示出今天中國的壁紙主題,第二個是能夠根據時間來獲取壁紙的主題和故事,而後使用列表控件把主要國家的壁紙和故事展現出來,同時用戶能夠對壁紙進行相關的操做,如在瀏覽器打開,收藏等功能。windows

23.2 獲取Bing壁紙的網絡接口

    Bing壁紙獲取的網絡接口網址格式以下所示:瀏覽器

http://appserver.m.bing.net/BackgroundImageService/TodayImageService.svc/GetTodayImage?dateOffset=0&urlEncodeHeaders=true&osName=windowsPhone&osVersion=8.10&orientation=480x800&deviceName=WP8&mkt=en-US微信

    這個接口能夠經過HTTP的Get請求來獲取,能夠直接在瀏覽器中打開連接變能夠獲取到圖片的顯示效果如圖23.1所示。下面咱們來看一下接口連接所傳遞過去的一些參數的說明。網絡

    (1)dateOffset表示已通過去的天數,好比0表示是今天,1則表示是昨天,4表示是獲取4天前的壁紙,以此類推。架構

    (2)orientation表示是獲取的壁紙圖片的分辨率,你能夠設置爲480×800、1024×768和800×480。app

    (3)mkt表示是國家地區的語言編碼,你能夠經過不一樣的語言編碼來獲取不一樣的國家地區的Bing壁紙圖片和信息,好比能夠設置爲zh-CN、en-US等。異步

    那麼直接從使用該接口進行下載獲取到的數據是整張圖片的數據,若是要獲取到圖片的主題和故事,須要經過HTTP頭相關的參數來獲取。咱們再利用一下IE瀏覽器,在IE瀏覽器上再次打開上面的連接,而後從瀏覽器的設置選項,找到「F12開發人員工具」的選項,點擊啓動IE瀏覽器的開發人員工具,而後在這裏查看網絡請求的頭信息。找到網絡類別,選擇「詳細信息」->「響應標頭」就能夠看到HTTP請求返回的響應頭的信息,如圖23.2所示。在這個響應頭裏面咱們主要是要找到關於圖片主題和故事的信息,以下所示:async

    (1)Image-Info-Credit(包含了圖片的主題和版權信息)

         Microphotograph%20of%20giant%20salvinia,%20a%20water%20fern%20(%C2%A9%20Martin%20Oeggerli/Visuals%20Unlimited,%20Inc.)

    (2)Image-Info-Hotspot-1(圖片的熱點說明1

         Let's%20switch%20the%20magnification%20back%20to...;images;Something%20more%20familiar;giant%20salvinia;;

    (3)Image-Info-Hotspot-2(圖片的熱點說明2

         Microscope%20slides%20may%20remind%20you%20of%20science%20class,%20but%20don't%20worry:%20There%20won't%20be%20a%20quiz.;images;Just%20marvel%20at%20how%20amazing%20plants%20can%20look%20up%20close;microphotography%20plants;;

23.3 壁紙請求服務的封裝

    在咱們掌握了Bing壁紙的接口信息規則以後,接下來要作的事情就是根據業務的規則來封裝壁紙請服務,把與壁紙請求關聯的業務規則經過一個類來封裝起來,而後提供相關的方法給外部來調用。經過對應用程序相關的服務封裝成爲公共的方法或者接口這是在程序架構上最基本的原則,這樣的好處是不只僅能夠實現程序代碼的共享,還能夠實現解耦,程序邏輯清晰等好處。在咱們要封裝bing壁紙請求服務的時候,咱們首先要考慮的問題是業務的情景,而後根據這個情景咱們須要封裝一個什麼樣的方法?傳遞進來的是什麼參數?而後返回什麼樣的返回值?經過什麼方式返回結果?首先根據咱們的網絡接口和業務情景,能夠分析出來咱們要實現的功能是,根據時間來獲取當前的壁紙詳情,壁紙詳情會包括壁紙地址、壁紙主題、壁紙熱點說明這些信息,而後同一天還須要獲取多個國家的壁紙信息。經過這些分析,咱們知道要傳遞進來的參數是時間,而後獲取到的結果是多個國家在當天的壁紙信息。由於多個國家的壁紙信息,根據目前的接口狀況是須要發起屢次的請求才能獲取到,而且HTTP的請求是異步請求,所在當發起這個網絡服務請求時咱們是不少必要去提供當前的進度信息,所以咱們能夠提供一個進度條的事件來返回進度結果、異常消息、結果信息等。經過上面的分析,如今基本清晰了這個壁紙請求服務的類該怎麼封裝了,下面咱們來看一下封裝的類和代碼。

PictureInfo類:表示是壁紙信息的類,會包含了壁紙地址、主題、熱點信息。
 ------------------------------------------------------------------------------------------------------------------
    /// <summary>
    /// 壁紙圖片信息類
    /// </summary>
    public class PictureInfo
    {
        // 壁紙的熱點說明信息
        public List<string> hotspot { get; set; }
        // 壁紙的主題
        public string imgTitle { get; set; }
        // 壁紙圖片的地址
        public Uri imageUri { get; set; }
        // 壁紙位圖對象
        public BitmapImage image { get; set; }
        // 國家代碼
        public string countryCode { get; set; }
        // 壁紙圖片信息類的初始化
        public PictureInfo(string _countryCode, string _imgTitle, string _imgUri)
        {
            countryCode = _countryCode;
            imgTitle = _imgTitle;
            imageUri = new Uri(_imgUri);
        }
    }

 

ProgressEventArgs類:表示獲取壁紙信息的進度返回的參數類。
 ------------------------------------------------------------------------------------------------------------------
    // 下載進度參數類
    public class ProgressEventArgs : EventArgs
    {
        // 進度的百分比值
        public int ProgressValue { get; set; }
        // 是否完成了全部圖片的下載
        public bool Complete { get; set; }
        // 是否發生異常
        public bool IsException { get; set; }
        // 異常消息
        public string ExceptionInfo { get; set; }
        // 下載的圖片列表信息,未完成時爲null
        public List<PictureInfo> Pictures { get; set; }
    }
WallpapersService類:表示獲取壁紙信息的服務類,該類使用單例模式來設計,由於對於整個應用程序,這個服務類也只須要一個對象,更加適合設計成單例模式。
 ------------------------------------------------------------------------------------------------------------------
    /// <summary>
    /// 獲取壁紙信息的服務類
    /// </summary>
    public class WallpapersService
    {
        // 距離今天的天數,表示獲取壁紙的時間
        private int selectedDay;
        // 國家代碼
        private List<string> countries = new List<string>(new string[] { 
            "zh-CN", "fr-FR",  "de-DE","en-US",  "ja-JP","en-GB"});
        // 須要獲取的請求次數
        private int http_times;
        // 總的請求次數
        private int http_times_all;
        // 是否已經開始下載了
        private bool downloading = false;
        // 已經下載的圖片信息
        private Dictionary<int, List<PictureInfo>> allHaveDownloadPictures;
        // 完成進度事件
        public EventHandler<ProgressEventArgs> GetOneDayWallpapersProgressEvent;
        // 觸發完成進度事件的方法
        private void OnGetOneDayWallpapersProgressEvent(ProgressEventArgs progressEventArgs)
        {
            if (GetOneDayWallpapersProgressEvent != null)
            {
                GetOneDayWallpapersProgressEvent.Invoke(this, progressEventArgs);
            }
        }
        private static WallpapersService _Current;
        // 單例對象
        public static WallpapersService Current
        {
            get
            {
                if (_Current == null)
                    _Current = new WallpapersService();
                return _Current;
            }
        }
        // 初始化對象
        private WallpapersService()
        {
            allHaveDownloadPictures = new Dictionary<int, List<PictureInfo>>();
        }
        /// <summary>
        /// 獲取所選時間的圖片
        /// </summary>
        /// <param name="selectedDay">表示距離今天的時間,0表示今天,1表示昨天……</param>
        public void GetOneDayWallpapers(int day)
        {
            // 若是當前正在下載圖片則跳出該方法的調用
            if (downloading) return;
            // 把當前的服務標誌位正在下載
            downloading = true;
            selectedDay = day;
            // 若是當前並無該日期的數據則須要在字典對象裏面添加上
            if(!allHaveDownloadPictures.Keys.Contains(selectedDay))
            {
                allHaveDownloadPictures.Add(selectedDay, new List<PictureInfo>());
            }
            // 拼接網絡請求地址
            string format = "http://appserver.m.bing.net/BackgroundImageService/TodayImageService.svc/GetTodayImage?dateOffset=-{0}&urlEncodeHeaders=true&osName=windowsPhone&osVersion=8.10&orientation=480x800&deviceName=WP8Device&mkt={1}";
            http_times_all = http_times = countries.Count<string>();
            foreach (string country in countries)
            {
                // 判斷該請求是否已經請求過,經過其所對應的日期和國家
                if (allHaveDownloadPictures[selectedDay].Select(item => item.countryCode == country).Count() == 0)
                {
                    //圖片下載url
                    string bingUrlFmt = string.Format(format, selectedDay, country);
                    //開始下載
                    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(bingUrlFmt);
                    request.Method = "GET";
                    request.BeginGetResponse(result => this.responseHandler(result, request, country, bingUrlFmt), null);
                }
                else
                {
                    // 若是壁紙信息已經獲取過則不要再重複獲取,直接返回進度信息
                    SetProgress();
                }
            }
        }
        // 獲取的壁紙圖片信息回調方法
        private void responseHandler(IAsyncResult asyncResult, HttpWebRequest request, string myloc, string _imgUri)
        {
            HttpWebResponse response;
            try
            {
                response = (HttpWebResponse)request.EndGetResponse(asyncResult);
            }
            catch(Exception e)
            {
                downloading = false;
                // 返回異常信息
                OnGetOneDayWallpapersProgressEvent(
                    new ProgressEventArgs 
                    { 
                        IsException = true, 
                        Complete = false,
                        ExceptionInfo = e.Message,
                        ProgressValue = 0,
                        Pictures = null 
                    });
                return;
            }
            if (request.HaveResponse)
            {
                // 圖片的熱點說明信息
                List<string> _hotspot = new List<string>();
                string _imgTitle = "";
                // 經過HTTP請求頭傳輸圖片相關的信息
                foreach (string str in response.Headers.AllKeys)
                {
                    string str2 = str;
                    string str3 = response.Headers[str];
                    // 獲取圖片的說明信息和版權信息
                    if (str2.Contains("Image-Info-Credit"))
                    {
                        _imgTitle = WebUtility.UrlDecode(str3);
                    }
                    // 獲取圖片的熱點介紹信息
                    else if (str2.Contains("Image-Info-Hotspot-"))
                    {
                        string[] strArray = WebUtility.UrlDecode(str3).Replace(" ","").Split(new char[] { ';' });
                        _hotspot.AddRange(strArray);
                    }
                }
                PictureInfo info = new PictureInfo(myloc, _imgTitle, _imgUri);
                info.hotspot = _hotspot;
                allHaveDownloadPictures[selectedDay].Add(info);
            }
            Debug.WriteLine("allHaveDownloadPictures[selectedDay].Count:" + allHaveDownloadPictures[selectedDay].Count);
            // 返回進度信息
            SetProgress();
        }
        // 返回進度的信息
        private void SetProgress()
        {
            http_times--;
            bool finish = http_times == 0;
            if (finish)
                downloading = false;
            // 返回結果
            OnGetOneDayWallpapersProgressEvent(
           new ProgressEventArgs {
               IsException = false,
               Complete = finish, 
               ExceptionInfo = "", 
               ProgressValue = (int)(((float)(http_times_all - http_times) / (float)http_times_all) * 100),
               Pictures = allHaveDownloadPictures[selectedDay] 
           });
        }
    }

 

23.4 應用首頁的設計和實現

    那麼在這一小節咱們要實現的功能是Bing在線壁紙的首頁頁面,在首頁頁面主要是添加上最近幾天的壁紙的連接,點擊直接跳轉到壁紙詳情列表裏面,由於通常狀況大部分用戶會比較關注最近的幾天壁紙信息和主題,微軟的這個壁紙一般都是會和最近的新聞或者節日相關。固然咱們在首頁也提供自定義的選擇,讓用戶能夠自定義選擇幾天前的壁紙信息的獲取。首頁的背景直接使用了當天中國地區的壁紙圖片。

MainPage.xaml頁面主要代碼:應用首頁的設計和邏輯。
 ------------------------------------------------------------------------------------------------------------------
    <Page.Resources>
        <!--定義了一個顯示出用戶自定義日期的面板的動畫資源,動畫的效果是從上往下拉出來-->
        <Storyboard x:Name="showMorePicture">
            <DoubleAnimation Storyboard.TargetName="topTransform" Storyboard.TargetProperty="Y" From="-300" To="0" Duration="0:0:0.3"></DoubleAnimation>
        </Storyboard>
    </Page.Resources>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <Grid Opacity="0.5" Grid.RowSpan="2">
            <Grid.Background>
                <ImageBrush>
                    <ImageBrush.ImageSource>
                        <BitmapImage x:Name="background"></BitmapImage>
                    </ImageBrush.ImageSource>
                </ImageBrush>
            </Grid.Background>
        </Grid>
        <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,0,0,28">
            <TextBlock Text="Bing壁紙" FontSize="20"  />
        </StackPanel>
        <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
            <!--添加了5個HyperlinkButton控件,其中最後一個按鈕會觸發動畫來顯示出用戶自定義日期的面板-->
            <StackPanel VerticalAlignment="Bottom">
                <HyperlinkButton Content="今天壁紙" x:Name="today" Click="today_Click"></HyperlinkButton>
                <HyperlinkButton Content="昨天壁紙" x:Name="yesterday" Click="yesterday_Click"></HyperlinkButton>
                <HyperlinkButton Content="2天前壁紙" x:Name="twodayago" Click="twodayago_Click"></HyperlinkButton>
                <HyperlinkButton Content="3天前壁紙" x:Name="threedayago" Click="threedayago_Click"></HyperlinkButton>
                <HyperlinkButton Content="更早的壁紙" x:Name="other" Click="other_Click"></HyperlinkButton>
            </StackPanel>
        </Grid>
    <!--自定義日期的面板-->
    <StackPanel x:Name="topStackPanel" Orientation="Vertical"  Grid.RowSpan="2" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" Height="300" VerticalAlignment="Top">
        <!--面板默認是在屏幕最上方頂上,用戶一開始並看不到-->
        <StackPanel.RenderTransform>
            <TranslateTransform x:Name="topTransform" Y="-300"></TranslateTransform>
        </StackPanel.RenderTransform>
        <TextBlock Text="選擇時間:"  Margin="12 30 0 0" VerticalAlignment="Center"></TextBlock>
        <StackPanel Orientation="Horizontal" Margin="12 30 0 0">
            <!--使用兩個AppBarButton來控制日期的增長和減小-->
            <AppBarButton Icon="Remove" IsCompact="True" x:Name="minus_bar" Click="minus_bar_Click" VerticalAlignment="Center"/>
            <TextBlock Text="4" x:Name="dayNumber" Margin="20 0 20 0" FontSize="20" VerticalAlignment="Center"></TextBlock>
            <AppBarButton Icon="Add" IsCompact="True" x:Name="plus_bar" Click="plus_bar_Click" VerticalAlignment="Center"/>
            <TextBlock Text="天前的壁紙"  VerticalAlignment="Center" Margin="24 0 0 0"></TextBlock>
        </StackPanel>
        <!--經過按鈕事件來觸發跳轉到壁紙詳情列表頁面-->
        <Button Content="查看壁紙" x:Name="go" Click="go_Click"  Margin="20 30 0 0"></Button>
</StackPanel>
    </Grid>
MainPage.xaml.cs頁面主要代碼
 ------------------------------------------------------------------------------------------------------------------
    public sealed partial class MainPage : Page
    {
        private string TodayPictureUri = "http://appserver.m.bing.net/BackgroundImageService/TodayImageService.svc/GetTodayImage?dateOffset=-0&urlEncodeHeaders=true&osName=windowsphone&osVersion=8.10&orientation=480x800&deviceName=WP8Device&mkt=zh-CN";
        public MainPage()
        {
            this.InitializeComponent();
        }
        // 進入當前的頁面
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            background.UriSource = new Uri(TodayPictureUri);
        }
        // 查看今天壁紙
        private void today_Click(object sender, RoutedEventArgs e)
        {
            Frame.Navigate(typeof(DayPicturesPage), 0);
        }
        // 查看昨天壁紙
        private void yesterday_Click(object sender, RoutedEventArgs e)
        {
            Frame.Navigate(typeof(DayPicturesPage), 1);
        }
        // 查看兩天前壁紙
        private void twodayago_Click(object sender, RoutedEventArgs e)
        {
            Frame.Navigate(typeof(DayPicturesPage), 2);
        }
        // 查看三天前壁紙
        private void threedayago_Click(object sender, RoutedEventArgs e)
        {
            Frame.Navigate(typeof(DayPicturesPage), 3);
        }
        // 查看更早壁紙
        private void other_Click(object sender, RoutedEventArgs e)
        {
            showMorePicture.Begin();
        }
        // 查看更早壁紙,減小天數的圖標按鈕事件
        private void minus_bar_Click(object sender, RoutedEventArgs e)
        {
            int day = Int32.Parse(dayNumber.Text);
            if(day>0)
            {
                day--;
                dayNumber.Text = day.ToString();
            }
        }
        // 查看更早壁紙,增長天數的圖標按鈕事件
        private void plus_bar_Click(object sender, RoutedEventArgs e)
        {
            int day = Int32.Parse(dayNumber.Text);
            day++;
            dayNumber.Text = day.ToString();
        }
        // 前往查看自定義天數的壁紙
        private void go_Click(object sender, RoutedEventArgs e)
        {
            Frame.Navigate(typeof(DayPicturesPage), Int32.Parse(dayNumber.Text));
        }
    }

    Bing在線壁紙的首頁顯示的效果如圖23.3所示,點擊「更早的壁紙」按鈕會出現一個動畫,自定義的面板會從上面下拉下來,顯示的效果如圖23.4所示。

23.5 手機和平板不一樣分辨率的適配

接下來咱們要實現壁紙列表詳情頁面,在該列表裏會展現某一天的壁紙信息,採用水平滾動的列表來顯示壁紙的

在這裏對兩個地方作了特殊的適配,一個是「更早的壁紙」彈出層作了適配,還有一個地方是首頁的背景圖。下面先看下「更早的壁紙」彈出層的適配。

「更早的壁紙」彈出層的適配採用了適配觸發器的方式去實現,當應用程序的寬度大於600像素的時候,彈出層的StackPanel面板採用水平排列的方式,而且高度從300像素改成150像素,若是手機橫屏放置那麼該適配效果也同樣會生效。添加的適配代碼以下所示:

    <VisualStateManager.VisualStateGroups>
        <VisualStateGroup>
            <VisualState x:Name="SideBySideState">
                <VisualState.StateTriggers>
                    <AdaptiveTrigger MinWindowWidth="600" />
                </VisualState.StateTriggers>
                <VisualState.Setters>
                    <Setter Target="topStackPanel.Orientation" Value="Horizontal"/>
                    <Setter Target="topStackPanel.Height" Value="150"/>
                </VisualState.Setters>
            </VisualState>
        </VisualStateGroup>
    </VisualStateManager.VisualStateGroups>

當寬度大於500像素的時候,彈出層的顯示效果如圖23.5所示:

對首頁背景圖片的適配採用了後臺C#代碼來實現,當應用程序的寬度大於500像素的時候採用大分辨率的Bing圖片,實現的思路是經過Window.Current.SizeChanged事件來獲取應用程序的窗體變化狀況,而後再進行判斷是否選擇大分辨率的圖片。代碼以下所示:

    public MainPage()
    {
        this.InitializeComponent();
        Window.Current.SizeChanged += Current_SizeChanged;
    }

    private void Current_SizeChanged(object sender, Windows.UI.Core.WindowSizeChangedEventArgs e)
    {
        if (e.Size.Width <= 500)
        {
            background.UriSource = new Uri(TodayPictureUri);
        }
        else
        {
            background.UriSource = new Uri(TodayPictureUri_Big);
        }
    }

23.6 壁紙列表詳情和操做的實現

    接下來咱們要實現壁紙列表詳情頁面,在該列表裏會展現某一天的壁紙信息,採用水平滾動的列表來顯示壁紙的圖片顯示和壁紙的熱點信息說明,同時還提供了在瀏覽器打開和保存到應用文件的兩個按鈕操做功能。在該頁面就須要去調用獲取壁紙信息的服務類WallpapersService類的GetOneDayWallpapers方法來獲取壁紙列表的信息,同時經過GetOneDayWallpapersProgressEvent事件把請求的進度在頁面上顯示出來,獲取完成以後再把壁紙的信息綁定到列表控件。

DayPicturesPage.xaml文件主要代碼:使用列表顯示壁紙圖片和信息的詳情。
------------------------------------------------------------------------------------------------------------------
    <Page.Resources>
        <!--綁定轉換器:把國家代碼轉化國家的名稱-->
        <local:CountryNameConverter x:Key="CountryNameConverter" />
    </Page.Resources>
   ……
    <!--使用ItemsControl列表控件來顯示壁紙的信息-->
    <ItemsControl  Grid.Row="1"  x:Name="pictureList"  >
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <!--設置列表控件的項目水平排列-->
                <StackPanel Orientation="Horizontal"></StackPanel>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.Template>
            <ControlTemplate>
                <!--設置列表控件的面板爲水平垂直可滾動-->
                <ScrollViewer ScrollViewer.HorizontalScrollBarVisibility="Visible" ScrollViewer.VerticalScrollBarVisibility = "Visible">
                    <ItemsPresenter />
                </ScrollViewer>
            </ControlTemplate>
        </ItemsControl.Template>
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <!--列表控件模板綁定壁紙的顯示和相關的信息-->
                <Grid Width="340">
                    <Image Opacity="0.5"  Stretch="Uniform" >
                        <Image.Source>
                            <BitmapImage UriSource="{Binding imageUri}" ></BitmapImage>
                        </Image.Source>
                    </Image>
                    <!--綁定國家代碼-->
                    <TextBlock FontSize="20" Text="{Binding countryCode,Converter={StaticResource CountryNameConverter}}" Margin="24 30 0 0"></TextBlock>
                    <StackPanel Margin="24 90 0 0" >
                        <!--綁定壁紙主題-->
                        <TextBlock FontSize="20" Text="{Binding imgTitle}"  TextWrapping="Wrap"></TextBlock>
                        <!--使用ListView列表綁定熱點說明信息-->
                        <ListView ItemsSource="{Binding hotspot}" Height="300">
                            <ListView.ItemTemplate>
                                <DataTemplate>
                                    <TextBlock Text="{Binding}" FontSize="15" TextWrapping="Wrap"></TextBlock>
                                </DataTemplate>
                            </ListView.ItemTemplate>
                        </ListView>
                    </StackPanel>
                    <!--保存和查看按鈕-->
                    <StackPanel Orientation="Horizontal" HorizontalAlignment="Right" VerticalAlignment="Top" >
                        <AppBarButton Icon="View" Label="查看" x:Name="view" Click="view_Click"/>
                        <AppBarButton Icon="Save" Label="保存" x:Name="save" Click="save_Click"/>
                    </StackPanel>
                </Grid>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
    <!--進度信息面板,在網絡請求的過程顯示,請問完成以後隱藏-->
    <StackPanel VerticalAlignment="Center" x:Name="tips">
        <!--進度條-->
        <ProgressBar  x:Name="progress" ></ProgressBar>
        <!--進度信息顯示-->
        <TextBlock Text="" x:Name="info" HorizontalAlignment="Center" FontSize="30" TextWrapping="Wrap"></TextBlock>
    </StackPanel>
DayPicturesPage.xaml.cs文件主要代碼
------------------------------------------------------------------------------------------------------------------
    public sealed partial class DayPicturesPage : Page
    {
        public DayPicturesPage()
        {
            this.InitializeComponent();
        }
        // 進入頁面即開始加載網絡的壁紙圖片和信息
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            if (e.Parameter != null && e.Parameter is int)
            {
                // 訂閱進度事件的處理程序
                WallpapersService.Current.GetOneDayWallpapersProgressEvent += OnOneDayWallpapersProgressEvent;
                // 調用壁紙請求服務類來獲取壁紙信息
                WallpapersService.Current.GetOneDayWallpapers((int)e.Parameter);
            }
        }
        // 離開當前的頁面則移除訂閱的進度事件
        protected override void OnNavigatedFrom(NavigationEventArgs e)
        {
            WallpapersService.Current.GetOneDayWallpapersProgressEvent -= OnOneDayWallpapersProgressEvent;
            base.OnNavigatedFrom(e);
        }
        // 進度事件的處理程序
        private async void OnOneDayWallpapersProgressEvent(object sender, ProgressEventArgs e)
        { 
           await this.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
                {
                    if(e.IsException)
                    {
                        // 若是發生異常則顯示異常信息
                        info.Text = "獲取圖片異常:"+e.ExceptionInfo;
                    }
                    else
                    {
                        // 正常返回設置進度條的值
                        progress.Value = e.ProgressValue;
                        // 進度完整
                        if(e.Complete)
                        {
                            // 把顯示進度的面板隱藏
                            tips.Visibility = Visibility.Collapsed;
                            // 把壁紙信息綁定到列表中
                            pictureList.ItemsSource = e.Pictures;
                            Debug.WriteLine("e.Pictures.Count:" + e.Pictures.Count);
                        }
                    } 
                });
        }
        // 查看按鈕的事件處理程序
        private async void view_Click(object sender, RoutedEventArgs e)
        {
            PictureInfo pictureInfo = (sender as AppBarButton).DataContext as PictureInfo;
            // 在瀏覽器打開壁紙
            await Launcher.LaunchUriAsync(pictureInfo.imageUri);
        }
        // 保存按鈕的事件處理程序
        private async void save_Click(object sender, RoutedEventArgs e)
        {
            PictureInfo pictureInfo = (sender as AppBarButton).DataContext as PictureInfo;
            List<Byte> allBytes = new List<byte>();
            // 把壁紙的圖片文件保存到當前的應用文件裏面
            using (var response = await HttpWebRequest.Create(pictureInfo.imageUri).GetResponseAsync())
            {
                using (Stream responseStream = response.GetResponseStream())
                {
                    byte[] buffer = new byte[4000];
                    int bytesRead = 0;
                    while ((bytesRead = await responseStream.ReadAsync(buffer, 0, 4000)) > 0)
                    {
                        allBytes.AddRange(buffer.Take(bytesRead));
                    }
                }
            }
           var file = await ApplicationData.Current.LocalFolder.CreateFileAsync(
                       "bingPicture"+DateTime.Now.Ticks+".jpg", CreationCollisionOption.ReplaceExisting);
           await FileIO.WriteBytesAsync(file, allBytes.ToArray()); 
        }
    }

本文來源於《深刻淺出Windows 10通用應用開發》

源代碼下載:http://vdisk.weibo.com/u/2186322691

目錄:http://www.cnblogs.com/linzheng/p/5021428.html

歡迎關注個人微博@WP林政   微信公衆號:wp開發(號:wpkaifa)

Windows10/WP技術交流羣:284783431

相關文章
相關標籤/搜索