WindowsPhone7その2

昨日に引き続き、書いていこうと思う。

サンプルとか

内臓ストレージにパラメーターを保存する(設定画面での設定値保持など)

これは2つのやり方があります。

  • オブジェクトの状態が変更されたときに自動保存
  • あるボタン(設定保存ボタン等)を押したときに、その時の状態を明示的に保存

まず、どちらの場合も内臓ストレージに記述するために必要なクラスを以下に示します。

using System;
using System.IO.IsolatedStorage;
using System.Diagnostics;
using System.Collections.Generic;

namespace Project
{
    public class AppSettings
    {
        IsolatedStorageSettings isolatedStore;

        //保存したい項目、及びその初期値
        const string CheckBoxSettingsKeyName = "CheckBoxSettings";

        const bool CheckBoxSettingsDefault = false;
        //ここまで

        public AppSettings()
        {
            try
            {
                isolatedStore = IsolatedStorageSettings.ApplicationSettings;
            }
            catch (Exception e)
            {
                Debug.WriteLine("Exception while using IsolatedStorageSettings: " + e.ToString());
            }
        }


        public bool AddOrUpdateValue(string Key, Object value)
        {
            bool valueChanged = false;
            try
            {
                if (isolatedStore[Key] != value)
                {
                    isolatedStore[Key] = value;
                    valueChanged = true;
                }
            }
            catch (KeyNotFoundException)
            {
                isolatedStore.Add(Key, value);
                valueChanged = true;
            }
            catch (ArgumentException)
            {
                isolatedStore.Add(Key, value);
                valueChanged = true;
            }
            catch (Exception e)
            {
                Debug.WriteLine("Exception while using IsolatedStorageSettings: " + e.ToString());
            }

            return valueChanged;
        }


        public valueType GetValueOrDefault<valueType>(string Key, valueType defaultValue)
        {
            valueType value;
            try
            {
                value = (valueType)isolatedStore[Key];
            }
            catch (KeyNotFoundException)
            {
                value = defaultValue;
            }
            catch (ArgumentException)
            {
                value = defaultValue;
            }
            return value;
        }

        public void Save()
        {
            isolatedStore.Save();
        }

        //保存したい項目の保存用メソッド
        public bool TwitterCheckBoxStatus
        {
            get
            {
                return GetValueOrDefault<bool>(CheckBoxSettingsKeyName, CheckBoxSettingsDefault);
            }
            set
            {
                AddOrUpdateValue(CheckBoxSettingsKeyName, value);
                Save();
            }
        }
        //ここまで
    }
}

こんな感じのコードを用意します。AppSettings.csとかで保存してください。使う場合、コード中コメントした2か所に追加なり変更なりだけで使えると思います。特に変わったことをしないのであれば、メソッドのところは、そのままコピペして変数名だけ書き換えれば問題ないので、実質変数名と初期値だけ決めればこのファイルは記述できます。


次に前者のオブジェクトの状態が変更されたときに自動保存の場合のコードを示します。この場合は、.xamlファイルに以下の記述を書き足せば動作します。

    xmlns:local="clr-namespace:Project"

これは、先頭のphone:PhoneApplicationPageタグ内のパラメーターです。

    <phone:PhoneApplicationPage.Resources>
        <local:AppSettings x:Key="appSettings"></local:AppSettings>
    </phone:PhoneApplicationPage.Resources>

そして、加えて保存したい項目のパラメーターとして、たとえばCheckBoxなら

        IsChecked="{Binding Source={StaticResource appSettings}, Path=CheckBoxSettings, Mode=TwoWay}"

このような記述を加えます。StaticResourceのところが先ほど作ったクラス名、PathがKey名です。またTwoWayというのは変更があれば即時保存するという意味です。
今の場合CheckBoxのチェック状態を保持したいので上のようなパラメーターにBindingしましたが、当然どのようなパラメーターに対してもできるので好きなパラメーターを割り当ててください。


ここからは、あるボタン(設定保存ボタン等)を押したときに、その時の状態を明示的に保存したい場合の記述をします。この場合.xamlファイルの変更はいりません。ButtonをClickしたイベントの部分にだけ記述します。

        private AppSettings settings = new AppSettings();
        settings.TextBoxSettings = textBox1.Text;

つまるところ、Keyに対してsetなりgetなりすればそのまま扱えます。読み出しも同様に

        textBox1.Text = settings.TextBoxSettings;

のようにできます。とっても簡単です。これで、たとえば、ユーザーIDなどを保持して、設定画面でそれを書きかえられる等が実装できます。


また、これに関連してですが、あるPageにBackボタンで戻ってきた場合、コンストラクタは呼ばれません。その代わりに新しいページを読んだ場合と同じくOnNavigatedToが呼ばれるのでOverrideすると幸せになれます。

        protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
        {
            userNameText.Text = settings.TextBoxSettings;
        }