zoukankan      html  css  js  c++  java
  • <WP7>(六)手把手教你写天气预报程序:使用Isolatedstorage保存设置

    上一节完成了SetPage的布局和数据绑定。这一节就要做设置页面和主页面的交互了。

    我们在主页面点击设置按钮的时候,是不是应该给设置页面传一个参数?比如城市名称?还有在设置页面ListPicker应该选择的是当前选择的地区,不然每次都是两个北京就显得很不友好了。

    我们在SetPage怎么知道是当前选择的地区呢。给另一个界面传参数可以考虑用Uri的方法,比如/SetPage.xaml?cityname="长安" ,然后从URi里面把参数取出来,NavigationContext.QueryString["cityname"]取出来值。但是这里我不考虑这方法,因为我的选择城市只有一个,直接保存到Isolatedstorage就行了。在SetPage里面再取出来。不过大部分程序还得用传参数形式,毕竟不能写多个页面,要一个页面多用嘛。举个简单的例子,QQ的聊天框,总不能给每个好友都自定义一个 吧。

    还有就是天气更新问题,从SetPage设置后重新回到MainPage,天气是否需要更新呢,这个也是个问题,如果人家没改选择也点击保存后回到MainPage,更新是否太浪费了。在这个流量还是很贵的时代。还有就是每次启动程序进入的时候都要更新么,毕竟服务器那头数据没有更新,这头客户端去请求,返回的数据和原来的一样,又是浪费流量浪费电量。window phone其实有一个叫推送的东西,这个东西简单来说就是服务端有更新,就通过推送通知客户端更新,这样,即省了流量也省了电量。但是在这里就不展示推送的编写过程了。

    所以,我自己制定的规则是:保存上一次更新的天气数据。然后从SetPage回来判断下城市是否相同,不同更新,更新时间是否超过3小时,超过更新。

    那么就开始做吧。

    先在SetPage页面的ApplicationBar添加一个IconButton。图标用的是Dark文件夹下的appbar.save.rest.png。复制到工程的Icons目录。并且修改生成操作属性为内容。这不懂操作的参考上一节。并且添加click事件。

     

    <shell:ApplicationBarIconButton IconUri="/Icons/appbar.save.rest.png" Text="保存" Click="ApplicationBarIconButton_Click"/>

    先添加一个类来保存选择的城市信息。工程---右键---添加---类---命名为SelectedCity.cs---添加。

    在SelectedCity.cs上,首先添加命名空间

    using System.IO.IsolatedStorage;

    这里附上SelectedCity.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;
    using System.IO.IsolatedStorage;
    
    namespace WeatherForecast
    {
         /// <summary>
        /// 用来保存设置城市信息
        /// </summary>
        public class SelectedCity
        {
            private string _province;
            public string Province { 
                get {
                    return _province;
                } set {
                    _province = value;
                } 
            }
    
            private string _citycode;
            public string CityCode
            {
                get
                {
                    return _citycode;
                }
                set
                {
                    _citycode = value;
                }
            }
    
            private string _cityname;
            public string Cityname
            {
                get
                {
                    return _cityname;
                }
                set
                {
                    _cityname = value;
                }
            }
    
            
            #region 往Isolate的storageSettings保存和取回设置的城市信息
            public static void SaveIsolated(SelectedCity sc)
            {
                IsolatedStorageSettings iss = IsolatedStorageSettings.ApplicationSettings;
                iss["SelectedCity"] = sc;
            }
    
            public static SelectedCity GetIsolated()
            {
                IsolatedStorageSettings iss = IsolatedStorageSettings.ApplicationSettings;
                SelectedCity sc = null;
                SelectedCity temp = null;
                if (iss.TryGetValue("SelectedCity", out temp))//取值的时候要先判断是否存在
                    sc = temp;
                return sc;
            } 
            #endregion
        }
    }

    接下来,我们要编写的是保存按钮的事件:

    /// <summary>
            /// 保存设置并且返回MainPage
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void ApplicationBarIconButton_Click(object sender, EventArgs e)
            {
                string cityname = citylp.SelectedItem.ToString();
                string prov = provincelp.SelectedItem.ToString();
                string citycode = String.Empty;
                //从数据库取出城市的代码
                using (var db = new CityDataContext(CityDataContext.connectionString))
                {
                    var queries =
                        from c in db.CityInfos where (c.Province == prov && c.CityName == cityname) select c;
                    citycode = queries.First().CityCode;
                }
                SelectedCity.SaveIsolated(new SelectedCity { CityCode = citycode,Cityname = cityname,Province = prov});
                NavigationService.Navigate(new Uri("/WeatherForecast;component/MainPage.xaml",UriKind.Relative));
            }

     然后到WeatherInfo.cs里面添加如下成员,并且添加命名空间。

     

    public DateTime UpdateTime { get; set; }
    
    
            #region 保存天气信息到Isolatedstorage
            public static void SaveIsolated(WeatherInfo w)
            {
                IsolatedStorageSettings iss = IsolatedStorageSettings.ApplicationSettings;
                iss["WeatherInfo"] = w;
            }
    
            public static WeatherInfo GetIsolated()
            {
                IsolatedStorageSettings iss = IsolatedStorageSettings.ApplicationSettings;
                WeatherInfo w = null;
                WeatherInfo temp = null;
                if (iss.TryGetValue("WeatherInfo", out temp))//取值先判断值是否存在
                    w = temp;
                return w;
            } 
            #endregion

    接下来,要做的就是保存后,MainPage页面的天气更新问题。

    我们要做的是在更新的时候先判断是否需要更新,判断条件在前面说过了,如果不需要更新还得把Ui更新。大概方向如此,具体代码经过一些整合修改,贴出来有改动部分:

    SelectedCity sc = null;
            string uriFormat = "http://m.weather.com.cn/data/{0}.html";
    
            private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
            {
                UpdateWeather();
            }
    
    
            /// <summary>
            /// 判断是否需要更新天气,需要更新为True
            /// </summary>
            /// <returns></returns>
            bool isUpdated()
            {
                sc = SelectedCity.GetIsolated();
                weather = WeatherInfo.GetIsolated();
                if (sc == null)//如果从IsolatedStorage里面取到的为空,就是没有设置地区。则设置默认为北京
                {
                    sc = new SelectedCity();
                    sc.CityCode = "101010100";
                    sc.Cityname = "北京";
                    sc.Province = "北京";
                    return true;
                }
                if (weather == null)//如果从来没有更新过天气。就更新
                {
                    return true;
                }
                if (weather.UpdateTime == null || !sc.Cityname.Equals(weather.city))//如果更改了地区,或者没有更新过天气。更新
                    return true;
                TimeSpan ts1 = new TimeSpan(weather.UpdateTime.Ticks);
                TimeSpan ts2 = new TimeSpan(DateTime.Now.Ticks);
                TimeSpan ts = ts1.Subtract(ts2).Duration();
                if (ts.Hours >= 3)//如果更新时间差超过3小时,更新
                    return true;
                return false;
            }
    
            void UpdateWeather()
            {
    
                if (!isUpdated())
                {
                    UpdateUI();
                    return;
                }
                string uri = String.Format(uriFormat, sc.CityCode);
                WebClient wb = new WebClient();//用WebClient获取天气。
                wb.DownloadStringCompleted += new DownloadStringCompletedEventHandler(wb_DownloadStringCompleted);//添加Download完成事件
                wb.DownloadStringAsync(new Uri(uri, UriKind.Absolute));//开始异步Download
            }
    
    
    
            /// <summary>
            /// 下载完成后的处理事件
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            void wb_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
            {
                //判断是否下载成功
                if (e.Result.Length <= 0 || e.Error != null || e.Cancelled)
                {
                    MessageBox.Show("获取天气预报失败!");
                    return;
                }
    
                SelectedCity.SaveIsolated(sc);//保存更新好的城市信息
    
    
                JObject json = JObject.Parse(e.Result);//用Jobject解析json数据
                weather = 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"]
                };
    
                weather.UpdateTime = DateTime.Now;
                WeatherInfo.SaveIsolated(weather);//保存更新好的天气信息
    
                UpdateUI();
            }

    下面要做的是进入SetPage的时候进行数据绑定显示,要显示为用户已经选择的城市信息。

     方式是先设置省份的SelectedIndex然后,在SelectionChange事件选择地区

    修改或增加的代码如下:

    SelectedCity sc = null;
            private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
            {
    
                ProvLpDataBind();
            }
    
    
            void ProvLpDataBind()
            {
                //给省份的listpicker绑定数据
                provincelp.ItemsSource = prov;
                sc = SelectedCity.GetIsolated();
                if (sc == null)
                    return;
                int i;
                for (i = 0; i < prov.Length; i++)
                {
                    if (prov[i] == sc.Province)
                        break;
                }
                provincelp.SelectedIndex = i;
            }
    
            private void provincelp_SelectionChanged(object sender, SelectionChangedEventArgs e)
            {
                ListPicker lp = sender as ListPicker;
                string p = lp.SelectedItem.ToString();
                ProvSelectedChanged(p);
                
            }
    
            /// <summary>
            /// 由当前选择的省份给city的ListPicker绑定数据,并返回该省份所以城市名单
            /// </summary>
            /// <returns></returns>
            List<String> cityDataBind(String prov)
            {
                IList<CityInfoTable> list = null;
                using (CityDataContext db = new CityDataContext(CityDataContext.connectionString))
                {
                    IQueryable<CityInfoTable> queries =
                        from c in db.CityInfos where c.Province == prov select c;
                    list = queries.ToList();
                }
                List<String> l = new List<string>();
                foreach (var item in list)
                {
                    l.Add(item.CityName);
                }
                citylp.ItemsSource = l;
                return l;
            }
    
            /// <summary>
            /// 省份改变,地区绑定,并选择原来设置的地区
            /// </summary>
            /// <param name="prov"></param>
            void ProvSelectedChanged(String prov)
            {
                List<String> l = cityDataBind(prov);
                if (sc != null && sc.Province == prov)
                {
                    int i = l.IndexOf(sc.Cityname);
                    citylp.SelectedIndex = i;
                }
            }

    运行,成功!这节都是代码。。。。

     这节工程下载:chapter6

     

    继续学习:<WP7>(七)手把手教你写天气预报程序:加入TombStone(墓碑机制)

  • 相关阅读:
    RN的win7开发环境部署和问题解决
    Android EditText弹出软键盘实现页面标题头不动,软键盘弹出在编辑框下面
    android打包生成apk时自定义文件名版本号。自定义项目字段等等
    Android ConstraintLayout 约束布局属性
    AS基本设置
    PermissionUtils
    kotlin之字符串模板
    kotlin之字符串
    kotlin之数组
    kotlin之布尔类型
  • 原文地址:https://www.cnblogs.com/fengyun1989/p/2476978.html
Copyright © 2011-2022 走看看