到现在为止,我们只能显示一个城市的天气,可是如果想得到别的城市的天气呢,总不能去修改程序里的值啊.这样我们就需求添加一个选择城市的页面.
首先,我们要在MainPage.xaml页面中添加一个设置按钮,这个按钮呢,你自己做一个按钮也行,要是WM7为什么预留了一个ApplicationBar的功能,我们可以直接使用它就行,在每个xaml的页面中.这个功能的代码,已经为什么写好了,只是被注释掉了.它就在前台代码的最下面.
看到了,我们只要把它进行解开就行了.这里简单说一句<shell:ApplicationBarIconButton>就是
看到了吧,而且对于<shell:ApplicationBar.MenuItems>则是点击省略号后,显示的二级菜单位了,你可以自己去试一下.
一般来说我们刚解锁的这个applicationbar的图片全是X这个X表示的是没有图片.我们可以去SDK中去找我们自己需求的图片,地址是:
C;/programe file/Microsoft SDKs/window phone/v7.1/Icon/dark下面去选择你要的图片,然后将图片复制到你的项目中,然后修改图片的属性,Build Action:Content
Copy to Output: Copy if newer就可以了
/// <summary> /// 设置按钮点击事件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void ApplicationBarIconButton_Click(object sender, EventArgs e) { NavigationService.Navigate(new Uri("/SetCity.xaml", UriKind.Relative)); }
看到了,是不是很好看,而且选择起来,也相当方便
我们看一下前台代码:
<phone:PhoneApplicationPage xmlns:toolkit="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Toolkit" x:Class="WeatherForecast.SetCity" 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"> <phone:PhoneApplicationPage.Resources> <DataTemplate x:Key="GroupHeader"> <Border Background="{StaticResource PhoneAccentBrush}" Margin="{StaticResource PhoneTouchTargetOverhang}" Padding="{StaticResource PhoneTouchTargetOverhang}"> <TextBlock Text="{Binding Key}"></TextBlock> </Border> </DataTemplate> <DataTemplate x:Key="GroupItem"> <Border Background="{StaticResource PhoneAccentBrush}" Margin="{StaticResource PhoneTouchTargetOverhang}" Padding="{StaticResource PhoneTouchTargetOverhang}"> <TextBlock Text="{Binding Key}" Style="{StaticResource PhoneTextLargeStyle}"></TextBlock> </Border> </DataTemplate> <DataTemplate x:Key="ListHeader"> <TextBlock Text="选择城市" Style="{StaticResource PhoneTextTitle1Style}"></TextBlock> </DataTemplate> <DataTemplate x:Key="Itemtmp"> <Grid> <TextBlock Text="{Binding city}"></TextBlock> </Grid> </DataTemplate> </phone:PhoneApplicationPage.Resources> <!--LayoutRoot is the root grid where all page content is placed--> <Grid x:Name="LayoutRoot" Background="Transparent"> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <!--TitlePanel contains the name of the application and page title <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28"> <TextBlock x:Name="ApplicationTitle" Text="MY APPLICATION" Style="{StaticResource PhoneTextNormalStyle}"/> <TextBlock x:Name="PageTitle" Text="page name" 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"> <toolkit:LongListSelector x:Name="llsCity" SelectionChanged="llsCity_SelectionChanged" Background="Transparent" ItemTemplate="{StaticResource Itemtmp}" ListHeaderTemplate="{StaticResource ListHeader}" GroupHeaderTemplate="{StaticResource GroupHeader}" GroupItemTemplate="{StaticResource GroupItem}"> </toolkit:LongListSelector> </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>
LongListSelector控件,可以让你自己设计它的样式模板,包括信息,头部等.这里我们就采用了默认情况.
我们来看后台代码,还记得在1中我给的哪个xml文件吗,里面的所有城市的信息.在这里我们要用它来做数据源.
第一步,我们先建立一个类,表示,省,市,以及市的ID
/// <summary> /// 定义城市信息类 /// </summary> public class CityInfo { public string city { get; set; } public string province { get; set; } public string cityid { get; set; } }
/// <summary> /// 定义城市信息类 /// </summary> public class CityInfo { public string city { get; set; } public string province { get; set; } public string cityid { get; set; } } /// <summary> /// 重载接口 /// </summary> /// <typeparam name="TKey"><peparam> /// <typeparam name="TElement"><peparam> public class GroupingLayer<TKey, TElement> : IGrouping<TKey, TElement> { //分组数据 private readonly IGrouping<TKey, TElement> grouping; //初始化 public GroupingLayer(IGrouping<TKey, TElement> unit) { grouping = unit; } //唯一的键值 public TKey Key { get { return grouping.Key; } } //重载判断相等方法 public override bool Equals(object obj) { GroupingLayer<TKey, TElement> that = obj as GroupingLayer<TKey, TElement>; return (that != null) && (this.Key.Equals(that.Key)); } public IEnumerator<TElement> GetEnumerator() { return grouping.GetEnumerator(); } System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { return grouping.GetEnumerator(); } }
/// <summary> /// 从XML数据中取出省份,市信息 /// </summary> public void GetInfo() { var xDoc = XDocument.Load("data/city.xml"); List<CityInfo> listCity = new List<CityInfo>(); var info = from city in xDoc.Descendants("Citys") select new { province = city.Element("province").Value, cityc = city.Element("city").Value, cityid = city.Element("cityid").Value }; foreach (var c in info) { listCity.Add(new CityInfo() { province = c.province, city = c.cityc, cityid = c.cityid }); } var selected = from c in listCity group c by c.province into n select new GroupingLayer<string, CityInfo>(n); this.llsCity.ItemsSource = selected; }
这里的程序,就和(三)里的一样了,调用webclient写取得你要选择城市的天气.代码如下:
/// <summary> /// 选择城市时对数据进行更新 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void llsCity_SelectionChanged(object sender, SelectionChangedEventArgs e) { CityInfo c = this.llsCity.SelectedItem as CityInfo; if (c!=null) { webclient(c.cityid); } } /// <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 + ".html", UriKind.Absolute)); } /// <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(); UpdateXML(json); } catch (Exception ex) { MessageBox.Show("连接中央气象局出错!"); //ReadXml(); } }
/// <summary> /// 更新XML文件,取得最新的数据 /// </summary> /// <param name="json"></param> public void UpdateXML(JObject json) { if (iso.FileExists("weatherData.xml")) { iso.DeleteFile("weatherData.xml"); IsolatedStorageFileStream isfs = new IsolatedStorageFileStream("weatherData.xml", FileMode.Create, iso); XElement xe = new XElement("weatherInfo", new XElement("city", (string)json["weatherinfo"]["city"]), new XElement("cityid", (string)json["weatherinfo"]["cityid"]), new XElement("date_y", (string)json["weatherinfo"]["date_y"]), new XElement("week", (string)json["weatherinfo"]["week"]), new XElement("temp1", (string)json["weatherinfo"]["temp1"]), new XElement("temp2", (string)json["weatherinfo"]["temp2"]), new XElement("temp3", (string)json["weatherinfo"]["temp3"]), new XElement("temp4", (string)json["weatherinfo"]["temp4"]), new XElement("temp5", (string)json["weatherinfo"]["temp5"]), new XElement("temp6", (string)json["weatherinfo"]["temp6"]), new XElement("weather1", (string)json["weatherinfo"]["weather1"]), new XElement("weather2", (string)json["weatherinfo"]["weather2"]), new XElement("weather3", (string)json["weatherinfo"]["weather3"]), new XElement("weather4", (string)json["weatherinfo"]["weather4"]), new XElement("weather5", (string)json["weatherinfo"]["weather5"]), new XElement("weather6", (string)json["weatherinfo"]["weather6"]), new XElement("wind1", (string)json["weatherinfo"]["wind1"]), new XElement("wind2", (string)json["weatherinfo"]["wind2"]), new XElement("wind3", (string)json["weatherinfo"]["wind3"]), new XElement("wind4", (string)json["weatherinfo"]["wind4"]), new XElement("wind5", (string)json["weatherinfo"]["wind5"]), new XElement("wind6", (string)json["weatherinfo"]["wind6"]), new XElement("info", (string)json["weatherinfo"]["index48_d"])); XDocument xdoc = new XDocument(new XDeclaration("1.0", "utf-8", "yes"), new XComment("天气数据"), new XElement("root", xe)); StreamWriter sw = new StreamWriter(isfs); xdoc.Save(sw); sw.Close(); isfs.Close(); NavigationService.Navigate(new Uri("/MainPage.xaml?cityid=" + (string)json["weatherinfo"]["cityid"], UriKind.Relative)); } }
第一,正常情况你,天气情况不应该是时时刷新的,应该设置一下,每隔几小时刷新一次,
第二,现在只是保留了一个城市的信息,你可以修改一下,做到保留几个城市的信息.