(三)手把手教你寫天氣預報程序:運用WebClient獲取天氣和json數據解析


       上一節我們練習了UserControl,這次我們就要把UserControl運用到實際的布局上面來。

          首先,把MainPage中的原來的測試UserControl的代碼刪除,在ContentPanel添加代碼:

 

<Grid.ColumnDefinitions>
                <ColumnDefinition Width="250"/>
                <ColumnDefinition Width="200"/>
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="200"/>
                <RowDefinition Height="100"/>
                <RowDefinition Height="100"/>
                <RowDefinition Height="100"/>
                <RowDefinition Height="100"/>
            </Grid.RowDefinitions>
            <my:ForeCastTemplate x:Name="day1" Grid.Column="1" Grid.Row="1"
                                 Height="100" Width="200"/>
            <my:ForeCastTemplate x:Name="day2" Grid.Column="1" Grid.Row="2"
                                 Height="100" Width="200"/>
            <my:ForeCastTemplate x:Name="day3" Grid.Column="1" Grid.Row="3"
                                 Height="100" Width="200"/>
            <my:ForeCastTemplate x:Name="day4" Grid.Column="1" Grid.Row="4"
                                 Height="100" Width="200"/>
            <Image x:Name="todayImage" Height="200" Width="250"/>
            <TextBlock x:Name="todaytemp" Grid.Column="0" Grid.Row="1"
                           Width="250" Height="100" HorizontalAlignment="Left"
                           VerticalAlignment="Center" FontSize="40"/>
            <TextBlock x:Name="todayWhe" Grid.Column="1" Grid.Row="0"
                           Width="200" Height="200" HorizontalAlignment="Left"
                           VerticalAlignment="Center" FontSize="24"
                           TextWrapping="Wrap"/>
            <TextBlock x:Name="todaydate" Grid.Column="0" Grid.Row="2"
                           Width="250" Height="100" HorizontalAlignment="Left"
                           VerticalAlignment="Center" FontSize="24"
                           TextWrapping="Wrap"/>
            <TextBlock x:Name="wtInfo" TextWrapping="Wrap" Grid.Column="0"
                           Grid.Row="3" Grid.RowSpan="2" FontSize="24"/>

 

在設計框顯示如下:

 

 

這樣界面就這樣吧。感覺也沒啥好說的。

現在看WebClient。

 點擊圖中的右下角用紅框選擇的小按鈕或者點擊文檔大綱。

選擇PhoneApplicationPage。選擇好了。隨意找個地點擊一下,就成了圖中的顯示樣子。

然后選擇屬性。

這里顯示的是PhoneApplication的屬性。如果不是。重新點擊

 

 

然后在屬性頁面選擇事件:

 

然后找到Loaded,在右邊的框框雙擊,生成了一個PhoneApplicationPage_Loaded事件。編譯器自動幫你導向了事件處理

在這個Loaded事件中,我打算用WebClient獲取天氣信息。並且顯示到界面上。

 獲取天氣,就要用到天氣預報API。免費的API可以看我寫的這個:http://blog.csdn.net/fengyun1989/article/details/7341166。我用的天氣預報API是中央氣象台的。主要是因為這個API能夠獲取到縣城的天氣信息。而且預報的信息很全。缺點就是我只收集到了大約10個省份的城市代碼。

 這節我們就獲取北京的天氣。用到的Url是:http://m.weather.com.cn/data/101010100.html

返回的數據相當的多(因為詳細,json數據):

 

 
        
{"weatherinfo":{"city":"北京","city_en":"beijing","date_y":"2012年3月11日","date":"","week":"星期日","fchh":"11","cityid":"101010100","temp1":"6℃~-6℃","temp2":"9℃~-2℃","temp3":"13℃~0℃","temp4":"11℃~-1℃","temp5":"9℃~1℃","temp6":"10℃~3℃","tempF1":"42.8℉~21.2℉","tempF2":"48.2℉~28.4℉","tempF3":"55.4℉~32℉","tempF4":"51.8℉~30.2℉","tempF5":"48.2℉~33.8℉","tempF6":"50℉~37.4℉","weather1":"","weather2":"","weather3":"多雲轉晴","weather4":"晴轉多雲","weather5":"多雲轉陰","weather6":"","img1":"0","img2":"99","img3":"0","img4":"99","img5":"1","img6":"0","img7":"0","img8":"1","img9":"1","img10":"2","img11":"2","img12":"99","img_single":"0","img_title1":"","img_title2":"","img_title3":"","img_title4":"","img_title5":"多雲","img_title6":"","img_title7":"","img_title8":"多雲","img_title9":"多雲","img_title10":"","img_title11":"","img_title12":"","img_title_single":"","wind1":"微風","wind2":"微風","wind3":"微風","wind4":"微風","wind5":"微風","wind6":"微風","fx1":"微風","fx2":"微風","fl1":"小於3級","fl2":"小於3級","fl3":"小於3級","fl4":"小於3級","fl5":"小於3級","fl6":"小於3級","index":"","index_d":"天氣冷,建議着棉衣、皮夾克加羊毛衫等冬季服裝。年老體弱者宜着厚棉衣或冬大衣。","index48":"","index48_d":"天氣涼,建議着厚外套加毛衣等春秋服裝。體弱者宜着大衣、呢外套。因晝夜溫差較大,注意增減衣服。","index_uv":"中等","index48_uv":"中等","index_xc":"適宜","index_tr":"適宜","index_co":"較舒適","st1":"6","st2":"-4","st3":"8","st4":"0","st5":"13","st6":"2","index_cl":"較不宜","index_ls":"基本適宜","index_ag":"易發"}}
 
         
         
        

我們先新建一個類老保存需要的天氣信息。在工程上右鍵。添加。類。命名為WeatherInfo.cs,點擊添加。

 

 

添加如下成員變量:

     public string city { get; set; }
        public string cityid { get; set; }
        public string date_y { get; set; }
        public string week { get; set; }
        public string temp1 { get; set; }
        public string temp2 { get; set; }
        public string temp3 { get; set; }
        public string temp4 { get; set; }
        public string temp5 { get; set; }
        public string weather1 { get; set; }
        public string weather2 { get; set; }
        public string weather3 { get; set; }
        public string weather4 { get; set; }
        public string weather5 { get; set; }
        public string wind1 { get; set; }
        public string info { get; set; }  //index48_d

 

 PS:展示一個小技巧,添加成員變量快捷方式:prop + tab + tab.編譯器就能自動完成,剩下的修改下類型和命名就行了,如圖:

 


保存。現在回到MainPage.xaml.cs。

給PageLoad添加代碼:

 

    WebClient wb = new WebClient();
            //添加下載完成后的處理事件
            wb.DownloadStringCompleted += new DownloadStringCompletedEventHandler(wb_DownloadStringCompleted);
            //開始異步下載
            wb.DownloadStringAsync(new Uri("http://m.weather.com.cn/data/101010100.html", UriKind.Absolute));

 

 

在這里敲wb.DownloadStringCompleted的時候,后面的+=  ,然后是tab ,tab,編譯器就能幫助你自動生成處理函數。

 如下:

 

void wb_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
        {
            throw new NotImplementedException();
        }

 

 

現在要在下載完成的事件里做json數據處理並且賦值給控件。

 Json數據處理我用的是Jobject類,這個類使用起來很方便。其他的也做過嘗試,但是由於要處理的數據的復雜性,使用起來相當麻煩。

要用到JObject這類要到http://json.codeplex.com/下載這個類的dll。下載最新版,完成后,解壓,現在就添加DLL到工程里面。

具體操作如下:工程---右鍵---添加引用---瀏覽,找到剛才解壓的目錄,並且到Bin\WindowsPhone下---選擇哪個dll文件---確

 在MainPage.xaml.cs中引入命名空間

 

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

 

並且為MainPage類添加兩個城員變量。

WeatherInfo weather = null;

        //定義星期屬性,以便能得出后面的日期
        string[] weekMsg = { "星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日" };

然后給下載完成函數添加如下代碼:

void wb_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
        {
            if (e.Result.Length <= 0 || e.Error != null || e.Cancelled)
            {
                MessageBox.Show("獲取天氣預報失敗!");
                return;
            }

            JObject json = JObject.Parse(e.Result);//用Jobject解析json數據
            weather = new WeatherInfo
            {
                city = (string)json["weatherinfo"]["city"],
                cityid = (string)json["weatherinfo"]["cityid"],
                date_y = (string)json["weatherinfo"]["date_y"],
                week = (string)json["weatherinfo"]["week"],
                info = (string)json["weatherinfo"]["index48_d"],
                wind1 = (string)json["weatherinfo"]["wind1"],
                temp1 = (string)json["weatherinfo"]["temp1"],
                temp2 = (string)json["weatherinfo"]["temp2"],
                temp3 = (string)json["weatherinfo"]["temp3"],
                temp4 = (string)json["weatherinfo"]["temp4"],
                temp5 = (string)json["weatherinfo"]["temp5"],
                weather1 = (string)json["weatherinfo"]["weather1"],
                weather2 = (string)json["weatherinfo"]["weather2"],
                weather3 = (string)json["weatherinfo"]["weather3"],
                weather4 = (string)json["weatherinfo"]["weather4"],
                weather5 = (string)json["weatherinfo"]["weather5"]
            };
            MessageBox.Show(weather.city);
        } 

PS:天氣信息很多。只獲取5天預報,這里展示Json.net的簡單應用,Json.NET還支持XML數據解析,XML,json數據相互轉化等。具體參考JSON.NET的幫助文檔。

 

點擊運行。

 

成功獲取到了天氣。現在添加一個函數來更新控件。另外添加一個函數來判斷該天氣匹配的圖片的URI。

PS:這個圖片問題。由於我對天氣專有名詞不熟悉,天氣相關圖片不熟悉。所以這個圖片顯示就做得馬虎了。顯示天氣信息的圖片也很少。如果顯示有錯,那多包涵。這里也提供一些關於天氣的圖片資源(如果不嫌麻煩就自己慢慢做):http://dl.dbank.com/c0ln2ja9u6

 代碼如下:

 

 /// <summary>
        /// 下載完成后的處理事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void wb_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
        {
            //判斷是否下載成功
            if (e.Result.Length <= 0 || e.Error != null || e.Cancelled)
            {
                MessageBox.Show("獲取天氣預報失敗!");
                return;
            }

            JObject json = JObject.Parse(e.Result);//用Jobject解析json數據
            weather = new WeatherInfo
            {
                city = (string)json["weatherinfo"]["city"],
                cityid = (string)json["weatherinfo"]["cityid"],
                date_y = (string)json["weatherinfo"]["date_y"],
                week = (string)json["weatherinfo"]["week"],
                info = (string)json["weatherinfo"]["index48_d"],
                wind1 = (string)json["weatherinfo"]["wind1"],
                temp1 = (string)json["weatherinfo"]["temp1"],
                temp2 = (string)json["weatherinfo"]["temp2"],
                temp3 = (string)json["weatherinfo"]["temp3"],
                temp4 = (string)json["weatherinfo"]["temp4"],
                temp5 = (string)json["weatherinfo"]["temp5"],
                weather1 = (string)json["weatherinfo"]["weather1"],
                weather2 = (string)json["weatherinfo"]["weather2"],
                weather3 = (string)json["weatherinfo"]["weather3"],
                weather4 = (string)json["weatherinfo"]["weather4"],
                weather5 = (string)json["weatherinfo"]["weather5"]
            };
            UpdateUI();
        }

        /// <summary>
        /// 更新UI信息
        /// </summary>
        void UpdateUI()
        {
            day1.Temp = weather.temp2;
            day2.Temp = weather.temp3;
            day3.Temp = weather.temp4;
            day4.Temp = weather.temp5;
            todaytemp.Text = weather.temp1;
            todayWhe.Text = weather.weather1 + Environment.NewLine + weather.wind1;
            todaydate.Text = weather.date_y + Environment.NewLine + weather.week;
            wtInfo.Text = weather.info;
            PageTitle.Text = weather.city;
            int i;
            for (i = 0; i < 7; i++)
            {
                if (weekMsg[i] == weather.week)
                    break;
            }
            day1.Weekday = weekMsg[(i + 1) % 7];
            day2.Weekday = weekMsg[(i + 2) % 7];
            day3.Weekday = weekMsg[(i + 3) % 7];
            day4.Weekday = weekMsg[(i + 4) % 7];
            day1.ImageUri = GetImgUri(weather.weather2);
            day2.ImageUri = GetImgUri(weather.weather3);
            day3.ImageUri = GetImgUri(weather.weather4);
            day4.ImageUri = GetImgUri(weather.weather5);
            todayImage.Source = new BitmapImage(new Uri(GetImgUri(weather.weather1), UriKind.Relative));
        }

        /// <summary>
        /// 返回天氣圖片的Uri。圖片的Building屬性為Resource
        /// </summary>
        /// <param name="weather"></param>
        /// <returns></returns>
        String GetImgUri(string weather)
        {
            string uri = "/WeatherForecast;component/Images/";
            if (weather == "")
            {
                return uri + "sunday.jpg";
            }
            else if (weather == "")
            {
                return uri + "overcast.jpg";
            }
            else if (weather == "雷陣雨")
            {
                return uri + "ThunderShower.jpg";
            }
            else if (weather.Contains("多雲"))
            {
                return uri + "cloudy.jpg";
            }
            else if (weather.Contains(""))
            {
                return uri + "Rain.jpg";
            }
            else
            {
                return uri + "cloudy.jpg";
            }
        }

 

點擊運行:

 

 

好了。這節就到這了。如果有任何問題,就留言吧。這節代碼下載:http://dl.dbank.com/c0flztwms9

 

繼續學習:<WP7>(四)手把手教你寫天氣預報程序:本地數據庫SQL CE,XML數據解析


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM