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

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

2011030517584433.jpg2011030517591811.jpg

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

City.cs

ContractedBlock.gif ExpandedBlockStart.gif 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

ContractedBlock.gif ExpandedBlockStart.gif 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

ContractedBlock.gif ExpandedBlockStart.gif 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

ContractedBlock.gif ExpandedBlockStart.gif 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的格式如图

2011030518065922.jpg

第二个页面的代码

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
="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc
="http://schemas.openxmlformats.org/markup-compatibility/2006"
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" >

< Grid x:Name ="LayoutRoot" Background ="Transparent" >
< Grid.RowDefinitions >
< RowDefinition Height ="Auto" />
< RowDefinition Height ="*" />
</ Grid.RowDefinitions >
< StackPanel x:Name ="TitlePanel" Grid.Row ="0" Margin ="24,24,0,12" >
< TextBlock x:Name ="ApplicationTitle" Text ="天气预报" Style =" {StaticResource PhoneTextNormalStyle} " />
< TextBlock x:Name ="PageTitle" Text =" {Binding City} " Margin ="-3,-8,0,0" Style =" {StaticResource PhoneTextNormalStyle} " />
</ StackPanel >
< Grid x:Name ="ContentGrid" Grid.Row ="1" Margin ="12,0,12,0" >
< ListBox Height ="618" HorizontalAlignment ="Left" Margin ="0,5,0,0" Name ="ForecastList" VerticalAlignment ="Top" Width ="474" Grid.RowSpan ="2" SelectionChanged ="ForecastList_SelectionChanged" >
< ListBox.ItemTemplate > <!-- 数据绑定模板 -->
< DataTemplate >
< Grid >
< Grid.RowDefinitions >
< RowDefinition Height ="80" />
< RowDefinition Height ="80" />
< RowDefinition />
< RowDefinition Height ="*" MinHeight ="80" />
</ Grid.RowDefinitions >
< Grid.ColumnDefinitions >
< ColumnDefinition Width ="90" />
< ColumnDefinition Width ="70" />
< ColumnDefinition Width ="180" />
< ColumnDefinition Width ="90" />
</ Grid.ColumnDefinitions >
< TextBlock Text =" {Binding Day_of_week} " Foreground ="LightBlue" FontSize ="40" Grid.Column ="0" Grid.Row ="0" Grid.ColumnSpan ="2" />
< Image Source =" {Binding Icon} " Grid.Column ="0" Grid.Row ="0" VerticalAlignment ="Bottom" HorizontalAlignment ="Right" Grid.ColumnSpan ="2" />
< TextBlock Text ="最低温度(K)" FontSize ="30" Foreground ="LightBlue" Grid.Column ="0" Grid.Row ="1" Grid.ColumnSpan ="2" />
< TextBlock Text =" {Binding Low} " FontSize ="30" Foreground ="White" Grid.Column ="1" Grid.Row ="1" Grid.ColumnSpan ="2" VerticalAlignment ="Bottom" HorizontalAlignment ="Right" />
< TextBlock Text ="最高温度(K)" FontSize ="30" Foreground ="LightBlue" Grid.Column ="0" Grid.Row ="2" Grid.ColumnSpan ="2" />
< TextBlock Text =" {Binding High} " FontSize ="30" Foreground ="White" Grid.Column ="1" Grid.Row ="2" Grid.ColumnSpan ="2" VerticalAlignment ="Bottom" HorizontalAlignment ="Right" />
< TextBlock Text =" {Binding Condition} " FontSize ="25" Foreground ="White" Grid.Column ="0" Grid.Row ="3" Grid.ColumnSpan ="4" TextWrapping ="Wrap" />

</ Grid >
</ DataTemplate >
</ ListBox.ItemTemplate >
</ ListBox >
</ Grid >
</ Grid >
</ phone:PhoneApplicationPage >
 
  
using System.Windows.Controls;
using Microsoft.Phone.Controls;
using System.Windows.Navigation;

namespace WeatherForecast
{
public partial class ForecastPage : PhoneApplicationPage
{
Forecast forecast;

public ForecastPage()
{
InitializeComponent();
}

/// <summary>
/// 当该页面被链接打开时,会调用该事件
/// </summary>
protected override void OnNavigatedTo(NavigationEventArgs e)
{
// 获取传过来的City值
string cityPinyin = this .NavigationContext.QueryString[ " City " ];
forecast
= new Forecast();
// 获取天气类
forecast.GetForecast(cityPinyin);
// 设置页面数据绑定到forecast
DataContext = forecast;
// 设置ForecastList绑定到forecast.ForecastList
ForecastList.ItemsSource = forecast.ForecastList;
}

private void ForecastList_SelectionChanged( object sender, SelectionChangedEventArgs e)
{
ForecastList.SelectedIndex
= - 1 ;
ForecastList.SelectedItem
= null ;

}
}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值