Windows8 Metro開發 (04) : 儲存/讀取本地應用程式設定

來源:互聯網
上載者:User
Josè Mourinho的專欄 http://blog.csdn.net/zyc13701469860轉載請註明原作者和出處。
有些時候我們需要儲存應用程式的設定,如使用者的系統設定。在Android中,我們可以使用sharepreference。在Metro中我們該怎麼做呢? 儲存/讀取基本類型資料 Metro程式會把要儲存的資料寫入ApplicationData.Current.LocalSettings字典中,並儲存在本地。程式在開始啟動並執行時候會從本地初始化該字典。載入之前儲存的資料。這樣我們就可以方便的儲存/讀取基本類型資料了。我將其封裝成了一個工具類。
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using Windows.Storage;namespace Win8_Study.Pages{    class LocalDataUtil    {        #region 儲存/讀取基本類型資料        public static void SaveData(string key, object value)        {            ApplicationData.Current.LocalSettings.Values[key] = value;        }        public static object GetData(string key)        {            return ApplicationData.Current.LocalSettings.Values[key];        }        public static void RemoveData(string key)        {            ApplicationData.Current.LocalSettings.Values.Remove(key);        }        #endregion    }}

下面我們來看一個樣本:
預設顯示的字型大小為24,我們將其字型改為28後返回到首頁面,然後重新進入該頁面。你會發現字型的大小變為28了。重新啟動程式進入該頁面,你會發現字型的大小仍然為28。下拉式清單的選中項與字型大小是時刻對應的.
實現方法如下:1.每次進入該頁面的時候,首先擷取之前儲存的字型大小a.沒有擷取到將字型大小設為預設值b.擷取到將字型大小設為擷取的值2.使用者改變字型大小時,儲存改變後的值
    public sealed partial class LocalDataPage : Win8_Study.Common.LayoutAwarePage    {        private readonly string TEXT_VALUE = "國米_百度百科\n" +            "國際米蘭足球俱樂部(Football Club Internazionale Milano,簡稱 Inter 或 Internazionale)" +            "是一家位於意大利北部倫巴第區米蘭市的足球俱樂部。";        private readonly double TEXT_FONT_SIZE = 24;        private readonly string TEXT_FONT_SIZE_KEY = "LocalDataPage-TEXT_FONT_SIZE_KEY";        public LocalDataPage()        {            this.InitializeComponent();        }        protected override void LoadState(Object navigationParameter, Dictionary<String, Object> pageState)        {            Init();        }        private void Init()        {            //首先讀取之前儲存的設定,如果為空白設定成預設狀態            InitFontSize();            leftTextBlock.Text = TEXT_VALUE;        }        protected override void SaveState(Dictionary<String, Object> pageState)        {        }        #region 儲存程式設定        private void OnLeftComboBoxSelectionChanged(object sender, SelectionChangedEventArgs e)        {            var comboBox = sender as ComboBox;            var item = comboBox.SelectedItem as ComboBoxItem;            SetTextFontSize(Convert.ToDouble(item.Content));        }        private void SetTextFontSize(double size)        {            leftTextBlock.FontSize = size;            LocalDataUtil.SaveData(TEXT_FONT_SIZE_KEY, size);        }        private void InitFontSize()        {            var obj = LocalDataUtil.GetData(TEXT_FONT_SIZE_KEY);            double size = TEXT_FONT_SIZE;            if (obj != null)            {                size = Convert.ToDouble(obj);            }                foreach (var element in leftFontSizeComboBox.Items)            {                var item = element as ComboBoxItem;                if (item.Content.ToString().Equals(size.ToString()))                {                    leftFontSizeComboBox.SelectedItem = item;                    break;                }            }                    }        #endregion        ...    }

或許你會嘗試著用這種方法去非基本類型的資料(比如Page,Color什麼的)。嘿嘿,掛了吧。那麼我們該怎樣去儲存非基本類型的資料呢?比如一個包含學生資訊的集合?

儲存/讀取非基本類型的資料--序列化/還原序列化儲存程式的即時資料是十分必要的。比如你從網路上擷取了一些娛樂新聞並顯示給使用者,你需要將這些資料儲存下來,以便程式下次啟動並執行時候使用。下次運行程式的時候,這些資料就會變成本地的了,載入速度會非常快,因為你不需要再去從網路擷取資料。如果你不這樣做的話,使用者可能會在網路非常擁塞的情況下看到一個非常"乾淨"的螢幕。這個時候你的應用也許會被(應該是必須)。。。
舉一個"稍微"複雜點的例子現在有Student,Coder兩個類,它們都繼承了父類People。
using System;using System.Collections.Generic;using System.Linq;using System.Runtime.Serialization;using System.Text;using System.Threading.Tasks;namespace Win8_Study.Pages{    [DataContract]    public abstract class People    {        [DataMember]        public string Name { get; set; }        [DataMember]        public int Age { get; set; }        public People(string name,int age)        {            this.Name = name;            this.Age = age;        }    }    [DataContract]    public class Student : People    {        [DataMember]        public int Score { get; set; }        public Student(string name, int age, int score)            : base(name, age)        {            this.Score = score;        }    }    [DataContract]    public class Coder : People    {        [DataMember]        public int WorkYears { get; set; }        public Coder(string name, int age, int workYears)            : base(name, age)        {            this.WorkYears = workYears;        }    }}

我們需要在ListView上隨機顯示一些學生和程式員的資訊,並儲存下來。然後清空ListView,讀取儲存的資料,看結果與之前的是否相同。

建立學生和程式員資訊的方法很簡單,在這裡建立5-10條資訊,每條資訊的內容隨機顯示:

private List<People> GetPeopleDatas()        {            List<People> peoples = new List<People>();            Random ran = new Random(DateTime.Now.Millisecond);            int count = ran.Next(5) + 5;//5 - 10            for (int i = 0; i < count; ++i)            {                int type = ran.Next(2);                if (type == 0)                {                    peoples.Add(new Student("學生" + (i + 1), ran.Next(12) + 6, 60 + ran.Next(41)));                }                else                {                    peoples.Add(new Coder("程式員" + (i + 1), ran.Next(10) + 22, ran.Next(5)));                }            }            return peoples;        }

根據類別建立不同ListView項

private void OnRightRandomAddDataButtonClicked(object sender, RoutedEventArgs e)        {            _peoples = GetPeopleDatas();            SetListViewData(_peoples);        }
        private void SetListViewData(List<People> peoples)        {            itemListView.Items.Clear();            foreach (People p in peoples)            {                ListViewItem item = new ListViewItem();                item.FontSize = 20;                if (p is Student)                {                    Student s = p as Student;                    item.Content = string.Format("{0} 年齡:{1} 成績: {2}", s.Name, s.Age, s.Score);                }                else                {                    Coder c = p as Coder;                    item.Content = string.Format("{0} 年齡:{1} 工作時間: {2}年", c.Name, c.Age, c.WorkYears);                }                itemListView.Items.Add(item);            }        }


儲存資料

        private async void OnRightSaveDataButtonClicked(object sender, RoutedEventArgs e)        {            await SerializerUtil.XMLSerialize(_peoples,typeof(List<People>));            await PopupUtil.ShowMessageDialog(string.Format("儲存資料成功! item數量{0}",_peoples.Count), "提示");        }

注意到People,Student,Coder中的序列化標誌的嗎?不添加的話是無法序列化的。其中 SerializerUtil.XMLSerialize是我封裝的序列化代碼的方法,其實現方式如下:

        public static async Task XMLSerialize(object instance, Type type)        {            //取得當前程式存放資料的目錄            StorageFolder folder = Windows.Storage.ApplicationData.Current.LocalFolder;            //定義檔案名稱            string fileName = "LocalDataPage-list_data.xml";            //建立檔案,如果檔案存在就覆蓋            StorageFile newFile = await folder.CreateFileAsync(fileName, CreationCollisionOption.ReplaceExisting)            //將內容序列化至檔案            Stream newFileStream = await newFile.OpenStreamForWriteAsync();            DataContractSerializer ser = new DataContractSerializer(type, GetTypes());            ser.WriteObject(newFileStream, instance);            newFileStream.Dispose();        }

注意GetTypes()方法,在序列化的時候需要指定序列化對象的類型集合。在這裡需要序列化的資料類型有3個:People,Student,Coder。所以我們應該這樣設定:

private static ObservableCollection<Type> GetTypes()        {            //添加要序列化的類型            if (_Types == null)            {                _Types = new ObservableCollection<Type>();                _Types.Add(typeof(People));                _Types.Add(typeof(Student));                _Types.Add(typeof(Coder));            }            return _Types;        }

其中_Types是全域對象ObservableCollection<Type>。至此,資料就儲存好了。
讀取資料讀取資料也就是進行還原序列化,我們可以得到之前儲存的對象集合,其資料類型是List<People>,然後我們將該對象集合交給ListView顯示即可。

private async void OnRightLoadDataButtonClicked(object sender, RoutedEventArgs e)        {            try            {                var obj = await SerializerUtil.XMLDeserialize(typeof(List<People>));                _peoples = obj as List<People>;                SetListViewData(_peoples);                await PopupUtil.ShowMessageDialog(string.Format("讀取資料成功! item數量{0}", _peoples.Count),                    "提示");                return;            }            catch (FileNotFoundException)            {                            }            await PopupUtil.ShowMessageDialog("你還沒有儲存資料。", "提示");        }

還原序列化

 public static async Task<object> XMLDeserialize(Type type)        {            StorageFolder folder = Windows.Storage.ApplicationData.Current.LocalFolder;            string fileName = "LocalDataPage-list_data.xml";            StorageFile newFile = await folder.GetFileAsync(fileName);            Stream newFileStream = await newFile.OpenStreamForReadAsync();            //進行還原序列化            DataContractSerializer ser = new DataContractSerializer(type, GetTypes());            object instance = ser.ReadObject(newFileStream);            newFileStream.Dispose();            return instance;        }

可以看到讀取的資料與之前儲存的相同.我們的目的達到了。
程式啟動並執行效果如下:1.隨機顯示學生和程式員資訊:

2.儲存資料儲存檔案的內容

<ArrayOfPeople xmlns="http://schemas.datacontract.org/2004/07/Win8_Study.Pages" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><People i:type="Student"><Age>14</Age><Name>學生1</Name><Score>66</Score></People><People i:type="Coder"><Age>24</Age><Name>程式員2</Name><WorkYears>4</WorkYears></People><People i:type="Student"><Age>7</Age><Name>學生3</Name><Score>86</Score></People><People i:type="Coder"><Age>23</Age><Name>程式員4</Name><WorkYears>1</WorkYears></People><People i:type="Coder"><Age>25</Age><Name>程式員5</Name><WorkYears>2</WorkYears></People></ArrayOfPeople>
3.清除資料並讀取之前儲存的資料顯示效果同第一張圖.

專欄網址:http://blog.csdn.net/zyc13701469860/article/details/8194090


相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.