上一节,我们已经把显示后四天天气的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)); }
第二步:这里我们还要实现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("连接中央气象局出错!"); } }
可是这里有几个问题,我们还是得优先考虑一下,就是图片的显示,这个就需求单独的方法来处理.所以...
第三步:图片显示方法 (说实话,天气变化的情况太多了,本人也没有整明白到底有多少,上网查了一下,也没有查全,所以就根据平时自己能遇到的常天气进行了处理)
/// <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)); }
第四步:开始加载
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; }
ImageBrush ib = new ImageBrush(); ib.ImageSource = new BitmapImage(new Uri(GetBgpic(wi.weather1), UriKind.Relative)); this.LayoutRoot.Background = ib;
是不是爽多了.背景图片,你可以自己去找一些
http://download.csdn.net/detail/chenguang79/4414336
这是所有城市的天气代码.大家可以用一下,