Хранение объектов в IsolatedStorageSettings - PullRequest
4 голосов
/ 14 сентября 2011

У меня есть объект, который я хочу сохранить в IsolatedStorageSettings, который я не хочу повторно использовать при перезапуске приложения.

Моя проблема заключается в том, что код, написанный по какой-то причине, не запоминаетобъект при попытке доступа к ключу после его перезапуска.

namespace MyNameSpace
{
    public class WindowsPhoneSettings
    {
        private const string SelectedSiteKey = "SelectedSite";
        private IsolatedStorageSettings isolatedStore = IsolatedStorageSettings.ApplicationSettings;

        private T RetrieveSetting<T>(string settingKey)
        {
            object settingValue;
            if (isolatedStore.TryGetValue(settingKey, out settingValue))
            {
                return (T)settingValue;
            }
            return default(T);
        }

        public bool AddOrUpdateValue(string Key, Object value)
        {
            bool valueChanged = false;

            if (isolatedStore.Contains(Key))
            {
                if (isolatedStore[Key] != value)
                {
                    isolatedStore[Key] = value;
                    valueChanged = true;
                }
            }
            else
            {
                isolatedStore.Add(Key, value);
                valueChanged = true;
            }
            return valueChanged;
        }

        public MobileSiteDataModel SelectedSite
        {
            get
            {
                return RetrieveSetting<MobileSiteDataModel>(SelectedSiteKey);
            }
            set
            {
                AddOrUpdateValue(SelectedSiteKey, value);
                isolatedStore.Save();
            }
        }
    }
}

Затем я создаю экземпляр WindowsPhoneSettings в App.xaml.cs и создаю для него общий метод получения и установки.Чтобы иметь доступ к нему во всем приложении.Отладка показывает, что нужный объект хранится в изолированном хранилище, но при закрытии приложения и повторном открытии изолированное хранилище кажется пустым.Я пробовал это как на эмуляторе, так и на реальном устройстве.Как видите, я вызываю метод save при настройке объекта.

Что я здесь не так делаю?

Ответы [ 4 ]

4 голосов
/ 04 октября 2011

Я закончил тем, что сохранил настройки в файл в изолированном хранилище, так как IsolatedStorageSettings никогда не работал.

Итак, мой код закончился так:

public class PhoneSettings
{
    private const string SettingsDir = "settingsDir";
    private const string SettingsFile = "settings.xml";

    public void SetSettings(Settings settings)
    {
        SaveSettingToFile<Settings>(SettingsDir, SettingsFile, settings);
    }

    public Settings GetSettings()
    {
        return RetrieveSettingFromFile<Settings>(SettingsDir, SettingsFile);
    }

    private T RetrieveSettingFromFile<T>(string dir, string file) where T : class
    {
        IsolatedStorageFile isolatedFileStore = IsolatedStorageFile.GetUserStoreForApplication();
        if (isolatedFileStore.DirectoryExists(dir))
        {
            try
            {
                using (var stream = new IsolatedStorageFileStream(System.IO.Path.Combine(dir, file), FileMode.Open, isolatedFileStore))
                {
                    return (T)SerializationHelper.DeserializeData<T>(stream);
                }
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine("Could not retrieve file " + dir + "\\" + file + ". With Exception: " + ex.Message);
            }
        }
        return null;
    }

    private void SaveSettingToFile<T>(string dir, string file, T data)
    {
        IsolatedStorageFile isolatedFileStore = IsolatedStorageFile.GetUserStoreForApplication();
        if (!isolatedFileStore.DirectoryExists(dir))
            isolatedFileStore.CreateDirectory(dir);
        try
        {
            string fn = System.IO.Path.Combine(dir, file);
            if (isolatedFileStore.FileExists(fn)) isolatedFileStore.DeleteFile(fn); //mostly harmless, used because isolatedFileStore is stupid :D

            using (var stream = new IsolatedStorageFileStream(fn, FileMode.CreateNew, FileAccess.ReadWrite, isolatedFileStore))
            {
                SerializationHelper.SerializeData<T>(data, stream);
            }
        }
        catch (Exception ex)
        {
            System.Diagnostics.Debug.WriteLine("Could not save file " + dir + "\\" + file + ". With Exception: " + ex.Message);
        }
    }
}

И класс настроекпросто содержит материал, который я хочу сохранить.Это может быть:

class Settings
{
    private string name;
    private int id;

    public string Name
    {
        get { return name; }
        set { name = value; }
    }

    public int Id
    {
        get { return id; }
        set { id = value; }
    }
}

РЕДАКТИРОВАТЬ: Пример того, как SerializationHelper может быть реализовано

public static class SerializationHelper
{
    public static void SerializeData<T>(this T obj, Stream streamObject)
    {
        if (obj == null || streamObject == null)
            return;

        var ser = new DataContractJsonSerializer(typeof(T));
        ser.WriteObject(streamObject, obj);
    }

    public static T DeserializeData<T>(Stream streamObject)
    {
        if (streamObject == null)
            return default(T);

        var ser = new DataContractJsonSerializer(typeof(T));
        return (T)ser.ReadObject(streamObject);
    }
}
2 голосов
/ 14 сентября 2011

Объекты, хранящиеся в IsolatedStorageSettings, сериализуются с использованием DataContractSerializer и поэтому должны быть сериализуемыми.Убедитесь, что они могут быть или сериализовать (и десериализовать) их самостоятельно перед добавлением (и после удаления из) МКС.

Если при попытке извлечь элементы не было, возможно, что онидобавлено в первую очередь (из-за проблемы с сериализацией).

1 голос
/ 16 апреля 2013

Вот код, который я использую для сохранения объекта в изолированном хранилище и для загрузки объекта из изолированного хранилища -

private void saveToIsolatedStorage(string keyname, object value)
{
  IsolatedStorageSettings isolatedStore = IsolatedStorageSettings.ApplicationSettings;
  isolatedStore.Remove(keyname);
  isolatedStore.Add(keyname, value);
  isolatedStore.Save();
}

private bool loadObject(string keyname, out object result)
{
  IsolatedStorageSettings isolatedStore = IsolatedStorageSettings.ApplicationSettings;

  result = null;
  try
  {
    result = isolatedStore[keyname];
  }
  catch
  {
    return false;
  }
  return true;
}

Вот код, который я использую для вызова вышеуказанного -

private void SaveToIsolatedStorage()
{
  saveToIsolatedStorage("GameData", GameData);
}

private void LoadFromIsolatedStorage()
{
  Object temp;
  if (loadObject("GameData", out temp))
  {
    GameData = (CGameData)temp;
  }
  else
  {
    GameData.Reset();
  }
}

Обратите внимание, что объекты, которые я сохраняю и восстанавливаю, являются небольшими и сериализуемыми. Если мой объект содержит двумерный массив или какой-либо другой объект, который не сериализуем, тогда я выполняю свою собственную сериализацию и десериализацию перед использованием iso-хранилища.

0 голосов
/ 14 сентября 2011

Что если вы изменили RetrieveSetting<T> на это:

private T RetrieveSetting<T>(string settingKey)
{
  T settingValue;
  if(isolatedStore.TryGetValue(settingKey, out settingValue))
  {
    return (T)settingValue;
  }
  return default(T);
}

Обратите внимание, что извлекаемый объект объявляется как тип T вместо object.

...