Introduction and best practices for IsolatedStorageSettings
This article explains how to use IsolatedStorageSettings and illustrates a helper class which enables using saving & retrieving (many) settings parameters easily.
Article Metadata
Code Example
Tested with
Compatibility
Article
Introduction
IsolatedStorageSettings is a dictionary for permanent storing values in Isolated Storage in the form of key-value pair. All that you have to do to store a value - is to provide a key for this value and a value itself.
You can store anything you want that is serializable, for example: user settings, layout information or application state. All settings from IsolatedStorageSettings are accessible after application shutdown and run again.
In this tutorial we will create a simple application that keeps one boolean value and then we are going to extend it for more convenient use.
Storing one setting with IsolatedStorageSettings
- Run Visual Studio 2012
- Create new Windows Phone project (7.1 or 8.0)
- Navigate to MainPage.xaml and replace all control content with one checkbox:
<phone:PhoneApplicationPage x:Class="IsolatedStorageSample.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}">
<CheckBox Content="Switch option"
Name="chck"
Checked="chck_Checked"
Unchecked="chck_Unchecked"
VerticalAlignment="Top" />
</phone:PhoneApplicationPage> - Navigate to MainPage.xaml.cs and insert code for storing and retrieving the value:
using System.IO.IsolatedStorage;
using System.Windows;
namespace IsolatedStorageSample
{
public partial class MainPage
{
/// <summary>
/// Object for sync access to IsolatedStorage
/// </summary>
private readonly object _sync = new object();
private const string SwitchKeyName = "switch";
// Constructor
public MainPage()
{
InitializeComponent();
//checking if property exists, if no - create it
if (!IsolatedStorageSettings.ApplicationSettings.Contains(SwitchKeyName))
{
IsolatedStorageSettings.ApplicationSettings[SwitchKeyName] = true;
SaveSettings();
}
//the checkbox state initializing
chck.IsChecked = (bool) IsolatedStorageSettings.ApplicationSettings[SwitchKeyName];
}
private void chck_Checked(object sender, RoutedEventArgs e)
{
IsolatedStorageSettings.ApplicationSettings[SwitchKeyName] = true;
SaveSettings();
}
private void chck_Unchecked(object sender, RoutedEventArgs e)
{
IsolatedStorageSettings.ApplicationSettings[SwitchKeyName] = false;
SaveSettings();
}
/// <summary>
/// Saving settings to isolated storage
/// </summary>
private void SaveSettings()
{
lock (_sync)
{
IsolatedStorageSettings.ApplicationSettings.Save();
}
}
}
} - Run the application
Why do I use thread synchronization? Because I do not know where else I will decide to call SaveSettings in the future, it could be ThreadPool, Timer callback or anything else. IsolatedStorageSettings is easy to use.
But if you are going to have more than just one setting-value - syncing, keeping key name, checking if setting exists and saving each time it has been updated may become a headache. Better way is to implement all this functionality in a helper class only once.
Helper class for easy storage of more setting values
Now we are going to create new class and implement logic for storing and retrieving setting values. With this, it should save the setting values every time we update it (in a thread safe manner), it should automatically set the default value if setting does not exist and finally it should keep the key name - we have to provide it only once at property declaration.
We create two new classes: IsolatedStoragePropertyHelper and IsolatedStorageProperty as illustrated below.
using System.IO.IsolatedStorage;
namespace IsolatedStorageSample
{
/// <summary>
/// Helper class is needed because IsolatedStorageProperty is generic and
/// can not provide singleton model for static content
/// </summary>
internal static class IsolatedStoragePropertyHelper
{
/// <summary>
/// We must use this object to lock saving settings
/// </summary>
public static readonly object ThreadLocker = new object();
public static readonly IsolatedStorageSettings Store = IsolatedStorageSettings.ApplicationSettings;
}
/// <summary>
/// This is wrapper class for storing one setting
/// Object of this type must be single
/// </summary>
/// <typeparam name="T">Any serializable type</typeparam>
public class IsolatedStorageProperty<T>
{
private readonly object _defaultValue;
private readonly string _name;
private readonly object _syncObject = new object();
public IsolatedStorageProperty(string name, T defaultValue = default(T))
{
_name = name;
_defaultValue = defaultValue;
}
/// <summary>
/// Determines if setting exists in the storage
/// </summary>
public bool Exists
{
get { return IsolatedStoragePropertyHelper.Store.Contains(_name); }
}
/// <summary>
/// Use this property to access the actual setting value
/// </summary>
public T Value
{
get
{
//If property does not exist - initializing it using default value
if (!Exists)
{
//Initializing only once
lock (_syncObject)
{
if (!Exists) SetDefault();
}
}
return (T) IsolatedStoragePropertyHelper.Store[_name];
}
set
{
IsolatedStoragePropertyHelper.Store[_name] = value;
Save();
}
}
private static void Save()
{
lock (IsolatedStoragePropertyHelper.ThreadLocker)
{
IsolatedStoragePropertyHelper.Store.Save();
}
}
public void SetDefault()
{
Value = (T) _defaultValue;
}
}
}
You can extend this classes as you want (may be you want to save values only when application is shutting down?) or you can just copy this classes to your project and start working right now. Using IsolatedStorageProperty class is easier then IsolatedStorageSettings:
namespace IsolatedStorageSample
{
using System.Windows;
public partial class MainPage
{
//Setting declaration
static readonly IsolatedStorageProperty<bool> SwitchProperty = new IsolatedStorageProperty<bool>("switch",true);
public MainPage()
{
InitializeComponent();
chck.IsChecked = SwitchProperty.Value;
}
private void chck_Checked(object sender, RoutedEventArgs e)
{
SwitchProperty.Value = true;
}
private void chck_Unchecked(object sender, RoutedEventArgs e)
{
SwitchProperty.Value = false;
}
}
}
We still have only one setting but a lot of lines are gone! - With ten or more property-settings this class become indispensable.
Lets create another setting - FirstRunTimeProperty:
using System;
namespace IsolatedStorageSample
{
using System.Windows;
public partial class MainPage
{
static readonly IsolatedStorageProperty<bool> SwitchProperty = new IsolatedStorageProperty<bool>("switch",true);
/// <summary>
/// Keeps first run time
/// </summary>
static readonly IsolatedStorageProperty<DateTime> FirstRunTimeProperty = new IsolatedStorageProperty<DateTime>("firstruntime", DateTime.Now);
public MainPage()
{
InitializeComponent();
chck.IsChecked = SwitchProperty.Value;
Loaded+=OnLoaded;
}
private void OnLoaded(object sender, RoutedEventArgs routedEventArgs)
{
//MessageBox.Show - could freeze main thread for a long time
//Dont let it freeze the constructor
MessageBox.Show(FirstRunTimeProperty.Value.ToString());
//This MessageBox always shows time of first run
}
private void chck_Checked(object sender, RoutedEventArgs e)
{
SwitchProperty.Value = true;
}
private void chck_Unchecked(object sender, RoutedEventArgs e)
{
SwitchProperty.Value = false;
}
}
}
FirstRunTimeProperty let us know when was first application run.
You can run the application two or more times to test it.
A good practice is to create a special static class, that would contain all your settings in it, so you can access any property in a program at any time:
namespace IsolatedStorageSample
{
public static class SettingsContainer
{
public static readonly IsolatedStorageProperty<bool> TestProperty1
= new IsolatedStorageProperty<bool>("TestProperty1");
public static readonly IsolatedStorageProperty<string> TestProperty2
= new IsolatedStorageProperty<string>("TestProperty2", "This is a test property");
//...
}
}


Contents
Chintandave er - Thanks and Sub-edited!
Hi Jinek,
Thanks for the article. I have sub-edited it and apply below template.
You might want to check out wiki help articles Help:Formatting and Help:Wiki Article Review Checklist.
Thanks,
Chintan Dave.Chintandave er 07:57, 16 November 2012 (EET)
Jinek -
Thanks for editing, i'll check formatting articlesjinek 08:15, 16 November 2012 (EET)
Croozeus -
Thanks for the article Jinek. The article offers a good approach on how to store setting values of different datatypes without writing much code.
In terms of improvement, I feel you could explain the code snippets better. For example, how does the class function to work with any datatypes could be explained better. I tried to structured the sections better.
For the competition, I look forward to see more WP8 specific articles from you!
--Pankajcroozeus 11:51, 19 November 2012 (EET)
Hamishwillee - Subedited - some thoughts
Hi Jinek
I've subedited this a bit further for wiki style - mostly just using # for the later bullets.
In terms of the article structure, this is fairly easy to follow, and I think people will definitely learn something from it. I like how you linked to API reference on MSDN which is something that people sometimes forget. I would also add a link to http://msdn.microsoft.com/en-us/library/cc221360(v=vs.95).aspx (the HowTo) and http://msdn.microsoft.com/en-us/library/windowsphone/develop/ff402541(v=vs.105).aspx.
My main concern with this article is that I think (not a WP expert) it solves a problem that isn't a particularly worrying use case. That is fine, but you need to be specific about when this is most useful. I guess you kind of did by saying "many settings" but it isn't completely clear why this is so useful for many settings (its implied that this is due to ease of writing code).
What I mean by this is that in the settings are automatically saved when the app is closed. If you do want to do it manually then you'd probably do it when an app page is exited (ie as part of handling possibility of going dormant). Normally you'd do this in your UI thread, and since this class is synchronous, you'd keep the number of properties that need to be saved small. So I see this as useful if you need to save a LOT of properties regularly that will take some time to save and hence you'll need to run in another thread. In this case you'd also have to consider whether perhaps using one of the other mechanisms would be more appropriate in any case.
This is not my preferred style. What it does is talk about how your app is constructed where a better approach is to discuss what any app using this feature will need to do. So for example you say "Navigate to MainPage.xaml and replace all control content with one checkbox:" - because you've done it this way it is not obvious what is actually related to using settings - most of this is just infrastructure for clicking a button. I think this is what Pankaj means by asking for more comments. If you change this round I'd be tempted to put your explanation of "Why do I use thread synchronization?" up the top of the section - ie explain what you're going to do and why first.
In terms of the competition, as far as I can see there is nothing that is WP8 specific - this is generic Windows Phone. We can consider it as an entry, but as it isn't innovative, comprehensive of shows off a real world feature of WP8 it would not be a strong contender. It is a useful topic for the wiki, though would be even better if tidied up a little.
To be a strong competition entry on settings/files data it would need to do something innovative, comprehensive or show off a real world benefit for WP8. This topic does a pretty good job of explaining the new Win32 storage APIs supported on Windows Phone 8 at high level but it doesn't cover topics in great detail like when to select WP8 methods over WP7 methods or have examples (though such may exist), how to work with the different methods on both systems, benefits/tradeoffs of the changes. There might be an opportunity there.
Hope that makes sense. Thanks again for this topic!
Regards
Hamishhamishwillee 08:35, 20 November 2012 (EET)
Raghavrags - How to do the above when checkbox in Listbox DataTemplate?
I created a button to create multiple checkbox inside a listbox on no. of clicks for wp7. Below the codes I used for it.
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<TextBox x:Name="txtNewTask" HorizontalAlignment="Left" Height="72" TextWrapping="Wrap" VerticalAlignment="Top" Width="328"/> <Button x:Name="btnAdd" Content="add" HorizontalAlignment="Left" Margin="328,0,0,0" VerticalAlignment="Top" Width="123" Click="btnAdd_Click"/> <ListBox x:Name="lbToDoList" Margin="0,72,0,0"> <ListBox.ItemTemplate> <DataTemplate> <CheckBox Click="CheckBox_Click" Background="{x:Null}"> <StackPanel Orientation="Horizontal"> <TextBlock Text="{Binding}" Name="tbkTextName" VerticalAlignment="Center" Margin="5,0,5,0" /> </StackPanel> </CheckBox> </DataTemplate> </ListBox.ItemTemplate> </ListBox></Grid>
Now when the app is re-launched my app, the checkbox’s are unchecked (default state) and its state is not saved. Can you please help me to save the multiple checkbox's inside a listbox value or state?raghavrags 17:26, 6 May 2013 (EEST)