window phone7.1 天气预报教程(二)WebClient获取天气和json数据解析显示

  上一节,我们已经把显示后四天天气的usercontrol做完了.今天我们来做一点更有意思的,就是把天气真实的显示出来,这里面要用到的知识点是webClient和json这二点.

  好了,开始,我们先把mainpage.xaml页面的样式简单修改一下.

  代码如下:(这里我用的是测试页面-Page1.xaml)大家不要直接全页复制

  

<phone:PhoneApplicationPage 
    x:Class="WeatherForecast.Page1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
    xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:my="clr-namespace:WeatherForecast"
    FontFamily="{StaticResource PhoneFontFamilyNormal}"
    FontSize="{StaticResource PhoneFontSizeNormal}"
    Foreground="{StaticResource PhoneForegroundBrush}"
    SupportedOrientations="Portrait" Orientation="Portrait"
    mc:Ignorable="d" d:DesignHeight="768" d:DesignWidth="480"
    shell:SystemTray.IsVisible="True">

    <!--LayoutRoot is the root grid where all page content is placed-->
    <Grid x:Name="LayoutRoot" Background="Transparent" Loaded="LayoutRoot_Loaded">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="240*" />
            <ColumnDefinition Width="240*" />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <!--TitlePanel contains the name of the application and page title-->
        <StackPanel x:Name="TitlePanel" Margin="12,17,0,28" Grid.ColumnSpan="2">

            <TextBlock x:Name="PageTitle" Text="" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
        </StackPanel>

        <!--ContentPanel - place additional content here-->
        <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"  Grid.ColumnSpan="2">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="226*" />
                <ColumnDefinition Width="230*" />
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="162*" />
                <RowDefinition Height="104*" />
                <RowDefinition Height="112*" />
                <RowDefinition Height="116*" />
                <RowDefinition Height="113*" />
            </Grid.RowDefinitions>

            <my:ForecastTemplate x:Name="day1" Grid.Column="1" Grid.Row="1" Height="100" Width="230" Weekday="" Temp="" imageUrl=""></my:ForecastTemplate>
            <my:ForecastTemplate x:Name="day2" Grid.Column="1" Grid.Row="2" Height="100" Weekday="" Temp="" imageUrl="" ></my:ForecastTemplate>
            <my:ForecastTemplate x:Name="day3" Grid.Column="1" Grid.Row="3" Height="101" Width="230" Weekday="" Temp="" imageUrl="" ></my:ForecastTemplate>
            <my:ForecastTemplate x:Name="day4" Grid.Column="1" Grid.Row="4" Height="101" Width="230" Weekday="" Temp="" imageUrl="" ></my:ForecastTemplate>
            <Image x:Name="todayImage" Height="150" Width="225"></Image>
            <TextBlock x:Name="todaytemp" Text="" Grid.Column="0" Grid.Row="1" Width="225" Height="100" HorizontalAlignment="Left" VerticalAlignment="Center" FontSize="40"></TextBlock>
            <TextBlock x:Name="todaywhe"  Grid.Column="1" Grid.Row="0" Width="230" Height="150" HorizontalAlignment="Left" VerticalAlignment="Center" FontSize="24" TextWrapping="Wrap" Text=""></TextBlock>
            <TextBlock x:Name="todaydate" Text="" Grid.Column="0" Grid.Row="2" Width="225" Height="100" HorizontalAlignment="Left" VerticalAlignment="Center" FontSize="24" TextWrapping="Wrap"></TextBlock>
            <TextBlock x:Name="wtInfo"  Grid.Column="0" Grid.Row="3" TextWrapping="Wrap" Grid.RowSpan="2" FontSize="24"></TextBlock>
        </Grid>
    </Grid>
 
    <!--Sample code showing usage of ApplicationBar-->
    <!--<phone:PhoneApplicationPage.ApplicationBar>
        <shell:ApplicationBar IsVisible="True" IsMenuEnabled="True">
            <shell:ApplicationBarIconButton IconUri="/Images/appbar_button1.png" Text="Button 1"/>
            <shell:ApplicationBarIconButton IconUri="/Images/appbar_button2.png" Text="Button 2"/>
            <shell:ApplicationBar.MenuItems>
                <shell:ApplicationBarMenuItem Text="MenuItem 1"/>
                <shell:ApplicationBarMenuItem Text="MenuItem 2"/>
            </shell:ApplicationBar.MenuItems>
        </shell:ApplicationBar>
    </phone:PhoneApplicationPage.ApplicationBar>-->

</phone:PhoneApplicationPage>

页面设计比较简单的, 没有什么好多说的,这里只有一点就是我在

<Grid x:Name="LayoutRoot" Background="Transparent" Loaded="LayoutRoot_Loaded">
加了一个loaded事件,就是在页面加载的时候,要实现的事件.

下面我们来看一下后台的代码

这里面,要先说一下前面提到的二个知识点:

1,webClient:提供向 URI 标识的资源发送数据和从 URI 标识的资源接收数据的公共方法。

  这里呢,我们用到的就是从URI标识的资源接收数据.

2,json:什么时候用到呢,就是把从webClient取来的数据进行解析,因为得到的数据是json形式的,

  我们要用到一个json的dll文件,大家可以到 http://json.codeplex.com/ 去下,然后加载进项目

  这里的天气情况我是从中央气象台的API中提取的,它返回的值就是json值,我们看一下

  

{"weatherinfo":{"city":"哈尔滨","city_en":"haerbin","date_y":"2012年7月6日","date":"","week":"星期五","fchh":"11","cityid":"101050101",
"temp1":"31℃~20℃","temp2":"32℃~22℃","temp3":"33℃~23℃","temp4":"33℃~22℃","temp5":"31℃~22℃","temp6":"30℃~21℃",
"tempF1":"87.8℉~68℉","tempF2":"89.6℉~71.6℉","tempF3":"91.4℉~73.4℉","tempF4":"91.4℉~71.6℉","tempF5":"87.8℉~71.6℉",
"tempF6":"86℉~69.8℉","weather1":"晴","weather2":"晴","weather3":"多云","weather4":"晴转多云","weather5":"多云",
"weather6":"多云转晴","img1":"0","img2":"99","img3":"0","img4":"99","img5":"1","img6":"99","img7":"0","img8":"1",
"img9":"1","img10":"99","img11":"1","img12":"0","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":"南风3-4级转小于3级",
"wind2":"南风3-4级转西南风小于3级","wind3":"西南风3-4级转小于3级","wind4":"南风3-4级转小于3级","wind5":"东南风3-4级转小于3级",
"wind6":"东南风3-4级转小于3级","fx1":"南风","fx2":"南风","fl1":"3-4级转小于3级","fl2":"3-4级转小于3级","fl3":"3-4级转小于3级",
"fl4":"3-4级转小于3级","fl5":"3-4级转小于3级","fl6":"3-4级转小于3级","index":"炎热","index_d":"天气炎热,建议着短衫、短裙、短裤、
薄型T恤衫、敞领短袖棉衫等清凉夏季服装。","index48":"炎热","index48_d":"天气炎热,建议着短衫、短裙、短裤、薄型T恤衫、
敞领短袖棉衫等清凉夏季服装。","index_uv":"很强","index48_uv":"很强","index_xc":"适宜","index_tr":"适宜","index_co":"较不舒适","st1":"29",
"st2":"21","st3":"30","st4":"23","st5":"32","st6":"23","index_cl":"较适宜","index_ls":"极适宜","index_ag":"不易发"}}

这里简单做一下解释

city:城市名

city_en:城市的英文名

date_y:日期

week:星期

cityid:城市的代码

temp1:当天的温度 temp2不是第二天的,以此类推

weather1:当天天气

wind1:当天风向

index48_d:着装提示.

为了能够显示这些数据,我们需求加一个类文件用来存取这些数据,以便读取和赋值

WeatherInfo.cs

using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace WeatherForecast
{
    public class WeatherInfo
    {
        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 temp6 { 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 weather6 { get; set; }
        public string wind1 { get; set; }
        public string wind2 { get; set; }
        public string wind3 { get; set; }
        public string wind4 { get; set; }
        public string wind5 { get; set; }
        public string wind6 { get; set; }
        public string info { get; set; }
    }
}

好准备工作完事了.我们开始我们的后台编码:

第一步,我们要先进行加载中央气象局的数据,我写了一个方法:

/// <summary>
        /// 加载远程中央气象局数据
        /// </summary>
        public void webclient(string cityid)
        {
            WebClient wc = new WebClient();
            wc.DownloadStringCompleted += new DownloadStringCompletedEventHandler(wc_DownloadStringCompleted);
            wc.DownloadStringAsync(new Uri("http://m.weather.com.cn/data/" + cityid, UriKind.Absolute));
        }

这里说一下,这里的webClient 取数据是异步进行的.我相信大家看到这个wc.DownloadStringArync也就明了.

第二步:这里我们还要实现wc.DownloadStringCompleted这个方法,wc.DownloadStringCompleted这个方法是在异步获取完数据之后执行的.在这个方法里,我们就要把获取的天气数据读出来

/// <summary>
        /// 异步加载完成后,向气象类写数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void wc_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
        {
            try
            {
                if (e.Result.Length < 1 || e.Error != null || e.Cancelled)
                {
                    MessageBox.Show("天气预报数据加载失败!原因:" + e.Error.Message);
                    return;
                }

                JObject json = JObject.Parse(e.Result);
                wi = 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"]
                };

                
                Update();
            }
            catch (Exception ex)
            {

                MessageBox.Show("连接中央气象局出错!");
                
            }
        }

这里面有一个方法Update()大家一眼就能看出是做什么的,对,它是把得到的数据赋值给前台的控制了.

可是这里有几个问题,我们还是得优先考虑一下,就是图片的显示,这个就需求单独的方法来处理.所以...

第三步:图片显示方法 (说实话,天气变化的情况太多了,本人也没有整明白到底有多少,上网查了一下,也没有查全,所以就根据平时自己能遇到的常天气进行了处理)

/// <summary>
        /// 根据天气情况加载图片
        /// </summary>
        /// <param name="weather"></param>
        /// <returns></returns>
        public string Getpic(string weather)
        {
            string uri = "Images/";
            if (weather == "晴")
            {
                uri += "sunday.png";
            }
            else if (weather == "阴")
            {
                uri += "overcast.png";
            }
            else if (weather == "雷阵雨")
            {
                uri += "ThunderShower.png";
            }
            else if (weather.Contains("云"))
            {
                uri += "cloudy.png";
            }
            else if (weather == "雨")
            {
                uri += "Rain.png";
            }
            else if (weather.Contains("雨") && weather != "雨" && weather != "雷阵雨")
            {
                uri += "Rain.png";
            }
            else
            {
                uri += "sunday.png";
            }


            return uri;
        }

第四步:给前台控件赋值

/// <summary>
        /// 将加载之后的数据绑定到前台控件中
        /// </summary>
        public void Update()
        {
            day1.Temp = wi.temp2;
            day2.Temp = wi.temp3;
            day3.Temp = wi.temp4;
            day4.Temp = wi.temp5;

            todaytemp.Text = wi.temp1;
            todaywhe.Text = wi.weather1 + Environment.NewLine + wi.wind1;
            todaydate.Text = wi.date_y + Environment.NewLine + wi.week;
            wtInfo.Text = wi.info;

            this.PageTitle.Text = wi.city;

            int i;
            for (i = 0; i < 7; i++)
            {
                if (weekMsg[i] == wi.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.imageUrl = Getpic(wi.weather2);
            day2.imageUrl = Getpic(wi.weather3);
            day3.imageUrl = Getpic(wi.weather4);
            day4.imageUrl = Getpic(wi.weather5);

            

           

            todayImage.Source = new BitmapImage(new Uri(Getpic(wi.weather1), UriKind.Relative));
        }

写到这里,明眼人一看就知道,你的wi和weeMsg哪来的,哈哈....在前面定义一下吧,同时把第一步中的方法给load.

第四步:开始加载

 

WeatherInfo wi = null;
        string[] weekMsg = { "星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日" };

        public Page1()
        {
            InitializeComponent();
        }

        private void LayoutRoot_Loaded(object sender, RoutedEventArgs e)
        {
            webclient("101050101.html");
        }

现在运行一下看一下效果如何:


哈哈....还不错吧,可是有一点少的是什么呢,背景啊.墨迹天气会根据不同的天气换不同的背景啊.这个我们也可以做一手吗,现在做一个简单的修改

前台:为LayoutRoot这个Grid控件加一个初始化背景

<Grid x:Name="LayoutRoot">
        <Grid.Background>
            <ImageBrush ImageSource="Images/bgsun.png">
            </ImageBrush>
        </Grid.Background>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="240*" />
            <ColumnDefinition Width="240*" />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

后台,加一个方法先:

 /// <summary>
        /// 根据天气情况设备背景图片
        /// </summary>
        /// <param name="weather"></param>
        /// <returns></returns>
        public string GetBgpic(string weather)
        {
            string uri = "Images/";
            if (weather == "晴")
            {
                uri += "bgsun.png";
            }
            else if (weather == "阴")
            {
                uri += "bgOvercast.png";
            }
            else if (weather == "雷阵雨")
            {
                uri += "bgThunderShower.png";
            }
            else if (weather.Contains("云"))
            {
                uri += "bgcloudy.png";
            }
            else if (weather.Contains("雪"))
            {
                uri += "bgSnow.png";
            }
            else if (weather.Contains("雨") && weather != "雨" && weather != "雷阵雨")
            {
                uri += "bgrain.png";
            }
            else
            {
                uri += "bgsun.png";
            }


            return uri;
        }

在Upade()方法中加入:

ImageBrush ib = new ImageBrush();
            ib.ImageSource = new BitmapImage(new Uri(GetBgpic(wi.weather1), UriKind.Relative));
            this.LayoutRoot.Background = ib;

再预览一下,什么样了.

window phone7.1 天气预报教程(二)WebClient获取天气和json数据解析显示_第1张图片

是不是爽多了.背景图片,你可以自己去找一些

http://download.csdn.net/detail/chenguang79/4414336

这是所有城市的天气代码.大家可以用一下,








你可能感兴趣的:(json,Date,exception,shell,String,button)