本篇将利用 Weather Reader User Control(WRUC) 模拟Windows 7 Gadgets 中的气象组件。WRUC 控件是使用C#和 WPF 制作的,首先下载WRUC 源代码,其实该控件已经实现了所有天气预报的功能,只需将DLL 库导入到其他项目使用即可。

WRUC 更新

    在使用WRUC 控件之前先了解一下它的工作模式,并完善其中的一些功能。通过源码可以看出控件是通过http://weather.service.msn.com 服务获取某地天气数据(XML格式),再将XML 读取出来用WPF 呈现给用户。下图为WRUC 默认的界面样式,可以看到控件默认是Redmond 地区的天气,虽然可以设置为其他地区,但还是希望程序运行时就是本地天气数据。同时还想在当日气温下方添加当日温度范围,并将所有温度改为摄氏度。

附件: ori.png

    在WRUC 项目中可以看到Settings1.settings 配置文件,打开后里面即为Redmond 地区信息,将其修改为本地信息,这里我全部改为Beijing。

附件: setfile_1.png

这样控件默认地区就是Beijing了,并且 DegreeType 可以将温度默认调整为摄氏度。

附件: setting.png

    地区和温度类型设置完成后,下面来添加当日气温范围数据,也就是获取当日最低和最高气温。在MsnWeatherDataProvider 类中当前气温信息是通过WeatherPoint 类完成的,所以先在WeatherPoint.cs 中添加最高温度和最低温度以及温度范围。
  1. private double highTemperature;
  2. public double HighTemperature
  3. {
  4.     get { return Math.Floor(highTemperature); }
  5.     set { highTemperature = value; }
  6. }

  7. private double lowTemperature;
  8. public double LowTemperature
  9. {
  10.     get { return Math.Floor(lowTemperature); }
  11.     set { lowTemperature = value; }
  12. }

  13. public string TemperatureRangeString
  14. {
  15.     get { return LowTemperature.ToString() + "°- " + HighTemperature.ToString() + "°"; }
  16. }
复制代码
回到MsnWeatherDataProvider 类,GetLatestWeatherReport 方法通过XmlTextReader 读取气象服务返回的XML 代码获得控件中所需的气温数据,那当日气温范围的数据在什么地方呢?这就需要看一看XML 代码返回的是什么内容了。

    通过浏览http://weather.service.msn.com/data.aspx?src=vista&wealocations=wc:CHXX0008 获得下面XML 代码,可见当日最低与最高气温数据就在第一个forecast 的low 和high 参数中。因为所有forecast 的数据早已被GetLatestWeatherReport 保存到WeatherReport 类的Forecast中,下面只需从Forecast 吊起就OK了。
  1. <?xml version="1.0" ?>
  2. <weatherdata>
  3.     <weather weatherlocationcode="wc:CHXX0008" weatherlocationname="Beijing, CHN"
  4.             zipcode="" encodedlocationname="Beijing%2c+CHN"
  5.             url=http://weather.msn.com/local.aspx?wealocations=wc:CHXX0008&q=Beijing%2c+CHN
  6.             imagerelativeurl="http://blst.msn.com/as/wea3/i/en-us/" degreetype="F" provider="Foreca"
  7.             attribution="Data provided by Foreca" attribution2="© Foreca"
  8.             lat="39.9125748" long="116.3889847" timezone="8" alert="">
  9.         <current temperature="86" skycode="32" skytext="Clear" date="2010-07-20" day="Tuesday"
  10.                 shortday="Tue" observationtime="12:00:00" observationpoint="Beijing"
  11.                 feelslike="88" humidity="52" windspeed="7" winddisplay="7 mph NNW" />
  12.         <forecast low="74" high="90" skycodeday="34" skytextday="Fair" date="2010-07-20"
  13.                   day="Tuesday" shortday="Tue" precip="10" />
  14.         <forecast low="77" high="93" skycodeday="34" skytextday="Fair" date="2010-07-21"
  15.                   day="Wednesday" shortday="Wed" precip="10" />
  16.         <forecast low="78" high="93" skycodeday="30" skytextday="Partly Cloudy" date="2010-07-22"
  17.                   day="Thursday" shortday="Thu" precip="30" />
  18.         <forecast low="77" high="95" skycodeday="26" skytextday="Cloudy" date="2010-07-23"
  19.                   day="Friday" shortday="Fri" precip="35" />
  20.         <forecast low="77" high="93" skycodeday="32" skytextday="Clear" date="2010-07-24"
  21.                   day="Saturday" shortday="Sat" precip="35" />
  22.         <toolbar timewindow="60" minversion="1.0.1965.0" />
  23.     </weather>
  24. </weatherdata>
复制代码
从GetLatestWeatherReport 得知forecast(预报) 数据存在result.Forecast 中。

result.Forecast.Add(forecast);

current(当日)数据存在result.LatestWeather 中。

result.LatestWeather = current;

那么只需在result.Location = location; 前添加下面两行代码即可,因为当日forecase 是第一组数据,所以Index 应该为0。
  1. result.LatestWeather.HighTemperature = result.Forecast[0].HighTemperature;
  2. result.LatestWeather.LowTemperature = result.Forecast[0].LowTemperature;
  3. result.Location = location;
复制代码
最后在WeatherReaderUI.xaml 的MainGrid 中将TemperatureRangeString 显示在TextBlock 就可以了。
  1. <TextBlock Foreground="{Binding Path=TextColor}" HorizontalAlignment="Right"
  2.           Margin="0,64,43,0" VerticalAlignment="Top" Width="Auto" Height="Auto"
  3.           Text="{Binding Path=LatestWeather.TemperatureRangeString, Mode=OneWay}"
  4.           TextWrapping="Wrap" x:Name="currentTempRangeText"
  5.           RenderTransformOrigin="0.5,0.5">
  6.     <TextBlock.RenderTransform>
  7.         <TransformGroup>
  8.             <ScaleTransform ScaleX="1" ScaleY="1"/>
  9.             <SkewTransform AngleX="0" AngleY="0"/>
  10.             <RotateTransform Angle="0"/>
  11.             <TranslateTransform X="0" Y="0"/>
  12.         </TransformGroup>
  13.     </TextBlock.RenderTransform>
  14. </TextBlock>
复制代码
TOP