现在的位置: 首页 > 综合 > 正文

Windows Phone 7 网络编程之天气预报应用

2012年09月10日 ⁄ 综合 ⁄ 共 9781字 ⁄ 字号 评论关闭

    天气预报应用是通过异步调用Google天气api(http://www.google.com/ig/api?weather=城市拼音),对其进行xml的数据解析,将其数据简单的展现出在Windows Phone 7的客户端上。

首页的城市数据绑定类,以及预设好的城市列表

City.cs

View Code

using System.ComponentModel;

namespace WeatherForecast
{
/// <summary>
/// 城市绑定类
/// </summary>
public class City : INotifyPropertyChanged
{
private string cityPinyin;//城市拼音
private string province;//省份
private string cityName;//城市名称

public string CityPinyin
{
get
{
return cityPinyin;
}
set
{
if (value != cityPinyin)
{
cityPinyin
= value;
NotifyPropertyChanged(
"CityPinyin");
}
}
}

public string Province
{
get
{
return province;
}
set
{
if (value != province)
{
province
= value;
NotifyPropertyChanged(
"Province");
}
}
}

public string CityName
{
get
{
return cityName;
}
set
{
if (value != cityName)
{
cityName
= value;
NotifyPropertyChanged(
"CityName");
}
}
}

public event PropertyChangedEventHandler PropertyChanged;

/// <summary>
/// 构造city类
/// </summary>
public City(string cityPinyin, string province, string cityName)
{
CityPinyin
= cityPinyin;
Province
= province;
CityName
= cityName;
}

/// <summary>
///用于绑定属性值改变触发的事件,动态改变
/// </summary>
private void NotifyPropertyChanged(string property)
{
if (PropertyChanged != null)
{
PropertyChanged(
this, new PropertyChangedEventArgs(property));
}
}
}
}

Cities.cs

View Code

using System.Collections.ObjectModel;

namespace WeatherForecast
{
/// <summary>
/// 继承 ObservableCollection<City>用户数据绑定
/// </summary>
public class Cities : ObservableCollection<City>
{
public Cities() { }
/// <summary>
/// 设置默认的绑定城市 利用App类里面定义的静态变量cityList
/// </summary>
public void LoadDefaultData()
{
App.cityList.Add(
new City("Shenzhen", "广东省", "深圳市"));
App.cityList.Add(
new City("Beijing", "北京市", "北京市"));
App.cityList.Add(
new City("Shanghai", "上海市", "上海市"));
App.cityList.Add(
new City("Guangzhou", "广东省", "广州市"));
App.cityList.Add(
new City("Yangjiang", "广东省", "阳江市"));
}
}
}

对首页城市列表的绑定需要在app程序启动类里面赋值

App.xaml.cs需要添加获取城市列表的代码

      public static Cities cityList;//绑定的城市列表

      ……

      private void Application_Launching(object sender, LaunchingEventArgs e)
        {
            // 创建城市列表
            if ( cityList==null)
            {
                cityList = new Cities();
                cityList.LoadDefaultData();
            }
        }

首页的界面设计代码

<phone:PhoneApplicationPage
x:Class="WeatherForecast.MainPage"
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"
mc:Ignorable
="d" d:DesignWidth="480" d:DesignHeight="768"
FontFamily
="{StaticResource PhoneFontFamilyNormal}"
FontSize
="{StaticResource PhoneFontSizeNormal}"
Foreground
="{StaticResource PhoneForegroundBrush}"
SupportedOrientations
="Portrait" Orientation="Portrait"
shell:SystemTray.IsVisible
="True">
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
<TextBlock x:Name="PageTitle" Text="天气预报" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
</StackPanel>
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<ListBox Height="646" HorizontalAlignment="Left" Margin="6,0,0,0" Name="CityList" VerticalAlignment="Top" Width="474" SelectionChanged="CityList_SelectionChanged">
<ListBox.ItemTemplate><!--数据绑定-->
<DataTemplate>
<StackPanel x:Name="stackPanelCityList" Orientation="Vertical" >
<TextBlock HorizontalAlignment="Left" Foreground="{StaticResource PhoneForegroundBrush}" FontSize="40" Text="{Binding CityPinyin}"/>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Left">
<TextBlock Margin="0,0,10,0" FontSize="25" Text="省份:" Foreground="LightBlue"/>
<TextBlock Margin="0,0,10,0" FontSize="25" Text="{Binding Province}" Foreground="{StaticResource PhoneForegroundBrush}"/>
<TextBlock Margin="0,0,10,0" FontSize="25" Text="城市:" Foreground="LightBlue"/>
<TextBlock Margin="0,0,10,0" FontSize="25" Text="{Binding CityName}" Foreground="{StaticResource PhoneForegroundBrush}"/>
</StackPanel>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</Grid>
</phone:PhoneApplicationPage>
using System;
using System.Windows.Controls;
using Microsoft.Phone.Controls;
using System.Windows.Navigation;

namespace WeatherForecast
{
public partial class MainPage : PhoneApplicationPage
{
public MainPage()
{
InitializeComponent();
CityList.ItemsSource
= App.cityList;//绑定城市列表
}

/// <summary>
/// 获取天气预报事件
/// </summary>
private void CityList_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
// 如果列被选中
if (CityList.SelectedIndex != -1)
{
City curCity
= (City)CityList.SelectedItem;//获取当前选中的城市的绑定的类
this.NavigationService.Navigate(new Uri("/ForecastPage.xaml?City=" +
curCity.CityPinyin, UriKind.Relative));
//跳转向ForecastPage.xaml 并传递参数CityPinyin 接口要用到城市的拼音
}
}

/// <summary>
/// 跳转到ForecastPage.xaml页面前执行该事件
/// </summary>
protected override void OnNavigatedFrom(NavigationEventArgs args)
{
// 清空选中的列
CityList.SelectedIndex = -1;
CityList.SelectedItem
= null;
}
}
}

第二个界面  异步调用Google的天气api,解析xml,然后绑定到客户端

天气预报类

ForecastPeriod.cs

View Code

using System.ComponentModel;

namespace WeatherForecast
{
/// <summary>
/// 天气预报绑定类
/// </summary>
public class ForecastPeriod : INotifyPropertyChanged
{
private string day_of_week;//星期
private int low;//最低温度
private int high;//最高温度
private string icon;//图片地址
private string condition;//天气情况

public event PropertyChangedEventHandler PropertyChanged;

public ForecastPeriod()
{
}

public string Day_of_week
{
get
{
return day_of_week;
}
set
{
if (value != day_of_week)
{
this.day_of_week = value;
NotifyPropertyChanged(
"Day_of_week");
}
}
}

public int Low
{
get
{
return low;
}
set
{
if (value != low)
{
this.low = value;
NotifyPropertyChanged(
"Low");
}
}
}

public int High
{
get
{
return high;
}
set
{
if (value != high)
{
this.high = value;
NotifyPropertyChanged(
"High");
}
}
}

public string Icon
{
get
{
return icon;
}
set
{
if (value != icon)
{
this.icon = value;
NotifyPropertyChanged(
"Icon");
}
}
}

public string Condition
{
get
{
return condition;
}
set
{
if (value != condition)
{
this.condition = value;
NotifyPropertyChanged(
"Condition");
}
}
}

private void NotifyPropertyChanged(string property)
{
if (PropertyChanged != null)
{
PropertyChanged(
this, new PropertyChangedEventArgs(property));
}
}
}
}

天气预报列表类 以及异步调用解析的方法

Forecast.cs

View Code

using System;
using System.Net;
using System.Windows;
using System.ComponentModel;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Xml.Linq;


namespace WeatherForecast
{
/// <summary>
/// 天气类以及处理解析异步请求
/// </summary>
public class Forecast : INotifyPropertyChanged
{
// 天气预报的城市
private string city;
// 天气预报的时间
private string forecast_date;

public event PropertyChangedEventHandler PropertyChanged;

// 不同时间段的天气预报集合
public ObservableCollection<ForecastPeriod> ForecastList
{
get;
set;
}

public String City
{
get
{
return city;
}
set
{
if (value != city)
{
city
= value;
NotifyPropertyChanged(
"City");
}
}
}

public String Forecast_date
{
get
{
return forecast_date;
}
set
{
if (value != forecast_date)
{
forecast_date
= value;
NotifyPropertyChanged(
"Forecast_date");
}
}
}

public Forecast()
{
ForecastList
= new ObservableCollection<ForecastPeriod>();
}

private void NotifyPropertyChanged(string property)
{
if (PropertyChanged != null)
{
PropertyChanged(
this, new PropertyChangedEventArgs(property));
}
}
//////////////////////////////////////////////////////////////////////////////

/// <summary>
/// 获取Forecast类
/// </summary>
public void GetForecast(string cityPinyin)
{
UriBuilder fullUri
= new UriBuilder("http://www.google.com/ig/api");
fullUri.Query
= "weather=" + cityPinyin;
HttpWebRequest forecastRequest
= (HttpWebRequest)WebRequest.Create(fullUri.Uri);
ForecastUpdateState forecastState
= new ForecastUpdateState();
forecastState.AsyncRequest
= forecastRequest;
forecastRequest.BeginGetResponse(
new AsyncCallback(HandleForecastResponse),
forecastState);
}

/// <summary>
/// 异步获取信息
/// </summary>
/// <param name="asyncResult"></param>
private void HandleForecastResponse(IAsyncResult asyncResult)
{
ForecastUpdateState forecastState
= (ForecastUpdateState)asyncResult.AsyncState;
HttpWebRequest forecastRequest
= (HttpWebRequest)forecastState.AsyncRequest;
forecastState.AsyncResponse
= (HttpWebResponse)forecastRequest.EndGetResponse(asyncResult);
Stream streamResult;
string city = "";
string forecast_date = "";

// 创建一个临时的ForecastPeriod集合
ObservableCollection<ForecastPeriod> newForecastList =
new ObservableCollection<ForecastPeriod>();

try
{
streamResult
= forecastState.AsyncResponse.GetResponseStream();
//加载 XML
XElement xmlWeather = XElement.Load(streamResult);

// 解析XML
// http://www.google.com/ig/api?weather=Beijing

// 找到forecast_information节点获取city节点和forecast_date节点的信息
XElement xmlCurrent = xmlWeather.Descendants("forecast_information").First();
city
= (string)(xmlCurrent.Element("city").Attribute("data"));
forecast_date
= (string)(xmlCurrent.Element("forecast_date").Attribute("data"));

ForecastPeriod newPeriod;
foreach (XElement curElement in xmlWeather.Descendants("forecast_conditions"))
{
try
{
newPeriod
= new ForecastPeriod();
newPeriod.Day_of_week
= (string)(curElement.Element("day_of_week").Attribute("data"));
newPeriod.Low
= (int)(curElement.Element("low").Attribute("data"));
newPeriod.High
= (int)(curElement.Element("high").Attribute("data"));
newPeriod.Icon
= "http://www.google.com" + (string)(curElement.Element("icon").Attribute("data"));
newPeriod.Condition
= (string)(curElement.Element("condition").Attribute("data"));
newForecastList.Add(newPeriod);
}
catch (FormatException)
{

}
}
Deployment.Current.Dispatcher.BeginInvoke(()
=>
{
//赋值City Forecast_date
City = city;
Forecast_date
= forecast_date;
ForecastList.Clear();

// 赋值ForecastList
foreach (ForecastPeriod forecastPeriod in newForecastList)
{
ForecastList.Add(forecastPeriod);
}
});
}
catch (FormatException)
{
return;
}

}
}

public class ForecastUpdateState
{
public HttpWebRequest AsyncRequest { get; set; }
public HttpWebResponse AsyncResponse { get; set; }
}

}

xml的格式如图

第二个页面的代码

ForecastPage.xaml

<phone:PhoneApplicationPage
x:Class="WeatherForecast.ForecastPage"
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

抱歉!评论已关闭.