1. Problem
You want to create a simple notepad so the user can store notes locally and simply retrieve them later.
2. Solution
You must use the IsolatedStorageFile class to access isolated storage.
3. How It Works
The class that provides the ability to access data in isolated storage is IsolatedStorageFile, contained in the namespace System.IO.IsolatedStorage, which in turn is contained inside the mscorlib assembly. As you can see from the class diagram shown in Figure 1,
you are allowed a number of tasks including creating directories. In
this case, for example, you could ask the user whether to save data in a
folder hierarchy
4. The Code
You start from an
interface that will be composed essentially of a main page and two
buttons. In the main page, the user will insert the title of the note
itself. In the application bar, you will have two buttons: one to save
the note and another to display the page that contains the list of notes
already written and saved in isolated storage. While on the list page,
you will have only a list box in which every item will be a note that is
already saved. When a note is selected from the list, it will be loaded
on the main page.
...
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
<TextBlock x:Name="ApplicationTitle" Text="SIMPLE NOTE APPLICATION"
Style="{StaticResource PhoneTextNormalStyle}"/>
</StackPanel>
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<Grid.RowDefinitions>
<RowDefinition Height="45" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBox Grid.Row="0" Name="FilenameTextBox" Text="NoteName" />
<TextBox Grid.Row="1" Name="NoteTextBox" Text="Write your note here" />
</Grid>
</Grid>
<phone:PhoneApplicationPage.ApplicationBar>
<shell:ApplicationBar IsVisible="True" IsMenuEnabled="True">
<shell:ApplicationBarIconButton IconUri="/Images/save.jpg" Text="Save"
Click="SaveButton_Click" />
<shell:ApplicationBarIconButton IconUri="/Images/notes.jpg" Text="Open"
Click="ListButton_Click" />
</shell:ApplicationBar>
</phone:PhoneApplicationPage.ApplicationBar>
...
It will be inside the handler SaveButton_Click that you will use the IsolatedStorageFile and IsolatedStorageStream classes, which enable you to create a file in isolated storage and to write within it a text stream.
private void SaveButton_Click(object sender, EventArgs e)
{
try
{
using (var store = IsolatedStorageFile.GetUserStoreForApplication())
using (var stream = new IsolatedStorageFileStream(FilenameTextBox.Text,
FileMode.Create,
FileAccess.Write,
store))
{
StreamWriter writer = new StreamWriter(stream);
writer.Write(NoteTextBox.Text);
writer.Close();
}
}
catch (Exception)
{
MessageBox.Show("Error saving the file");
}
}
First you need the storage dedicated to your application, which will be automatically retrieved from the GetUserStoreForApplication
method that is based on your application. Then you create a stream to a
file that will store the content in your application. This filename is
contained in the Text field of the control FilenameTextBox. At this point, you just have to write the stream you have available, with a StreamWriter (remember to close the stream after you are finished).
If errors occur in the
preceding transactions, the application will show a message to the user
indicating that there was a problem.
The other handler used to display the page with the list of notes already saved will not be anything other than a call to the Navigate method of the NavigationService property (of the homonym type):
private void ListButton_Click(object sender, EventArgs e)
{
NavigationService.Navigate(new Uri("/Notes.xaml", UriKind.Relative));
}
On the page where you will present the list, you will override the OnNavigatedTo event handler, to load the list of all files created in your isolated storage:
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
using (var store =
System.IO.IsolatedStorage.IsolatedStorageFile.GetUserStoreForApplication())
{
this.NotesListBox.ItemsSource = store.GetFileNames();
}
}
Basically, you're passing as a
source of list box items the list of filenames in your store that will
be shown onscreen.
Click an item within the list to pass it as parameter of the main page via the following code:
private void Notes_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (e.AddedItems.Count > 0)
NavigationService.Navigate(new Uri(
string.Format("/MainPage.xaml?note={0}", e.AddedItems[0]),
UriKind.Relative));
}
At this point, to complete the code of this application, you need to only override the OnNavigatedTo method in the main page. Then you manage the opening of the note by using the following code:
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
if (NavigationContext.QueryString.ContainsKey("note"))
{
string filename = this.NavigationContext.QueryString["note"];
if (!string.IsNullOrEmpty(filename))
{
using (var store = System.IO.IsolatedStorage.IsolatedStorageFile
.GetUserStoreForApplication())
using (var stream = new IsolatedStorageFileStream(filename,
FileMode.Open,
FileAccess.ReadWrite,
store))
{
StreamReader reader = new StreamReader(stream);
this.NoteTextBox.Text = reader.ReadToEnd();
this.FilenameTextBox.Text = filename;
reader.Close();
}
}
}
}
There is not much
difference between this code and the code used to save data, except that
this time you first check whether a note to be opened has been passed.
If it has, you aim to open it instead of creating a new note, as you did
before when using a StreamReader to read and enter in the text box the body of the note that you read from the file.
5. Usage
From Visual Studio 2010, launch the application by pressing Ctrl+F5. The application displays, as shown in Figure 2. Write something and then click the button to save the note. Click to display the list of saved notes, as shown in Figure 3. (We had already saved some.) Click on another note that has been saved for loading and complete the cycle of the application.