(六)手把手教你寫天氣預報程序:使用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(墓碑機制)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM