Universal Windows 10 Apps Data Storage

Universal Windows 10 Apps Data Storage

UWPstorage1

Short introduction

When you start designing your app propably you do not think what will happen when user close. What will happen with the data collected by it. Today it is not enough to only create nice design, you have to also think how to store the data collected in the app by user.

In this article I would like to show how easily you can store the data in the Universal Windows 10 Apps.

The whole source code is available on my Git Hub account.

What do I need to start?

1) Visual Studio 2015 Community (for free) or higher

Let’s start

1) Open Visual Studio and create new blank Universal App project:

UWPstorage2

2) It is worth to stop for a moment here and show two types of app data:

1. Settings – this type of data is used to store app state and user preferences. This one should be used to store lightweight information about the app and it is not good idea to store large data objects – they should be stored in files described below.

In Settings you can store types like: Int, UInt, Single, Double, String, Char, DateTime, GUID or ApplicationDataCompositeValue (settings that must be serialized and deserialized atomically).

2. Files – this type of data should be used to store binary data and your own serialized types.

 

3) Let’s see how to use Settings in the UWP application:

1. Open “App.xaml” file and remove “RequestedTheme” tag:

UWPstorage3

2. Now opem “MainPage.xaml” file in the designer and add two buttons: “LightThemeButton” and “DarkThemeButton” like below:

 

 <StackPanel Orientation="Vertical" HorizontalAlignment="Center" VerticalAlignment="Center">
 <Button x:Name="LightThemeButton" Content="Set light theme" Click="LightThemeButton_Click"/>
 <Button x:Name="DarkThemeButton" Content="Set dark theme" Click="DarkThemeButton_Click" Margin="0,10,0,0"/>
 </StackPanel>

Now let’s see how to implement Settings in code behind:

We want to switch Application Theme when user click buttons (between Light and Dark):

Below is the code to handle buttons click and apply Application Theme accordingly:

 public sealed partial class MainPage : Page
  {
    public MainPage()
    {
     this.InitializeComponent();
    }

    private void setAppThemeTheme(ElementTheme requestedTheme)
    {
     RequestedTheme = requestedTheme;
    }

    private void LightThemeButton_Click(object sender, RoutedEventArgs e)
    {
      setAppThemeTheme(ElementTheme.Light);
    }

    private void DarkThemeButton_Click(object sender, RoutedEventArgs e)
    {
     setAppThemeTheme(ElementTheme.Dark);
    }
   }

Now it is time to save App Theme preference in Settings, Let’s see how to do it:

1. Firstly we have to get reference to app settings:

  var localSettings = ApplicationData.Current.LocalSettings;

Settings are working like dictionary so you can put key-value pair. To store selected App Theme we need to insert it like below (remember to use toString method – there is no direct way to insert Enum values):

 localSettings.Values["AppTheme"] = RequestedTheme.toString();

Now whenever user change the Theme we should save this preference in the Settings:

 var localSettings = ApplicationData.Current.LocalSettings;
 localSettings.Values["AppTheme"] = RequestedTheme.toString();

The whole code should look like below:

  public sealed partial class MainPage : Page
 {
   public MainPage()
   {
    this.InitializeComponent();
   }
 
   private void saveThemeInSettings()
   {
    var localSettings = ApplicationData.Current.LocalSettings;
    localSettings.Values["AppTheme"] = RequestedTheme.toString();
   }

   private void setAppThemeTheme(ElementTheme requestedTheme)
   {
   RequestedTheme = requestedTheme;
   saveThemeInSettings();
   }

  private void LightThemeButton_Click(object sender, RoutedEventArgs e)
  {
   setAppThemeTheme(ElementTheme.Light);
  }

  private void DarkThemeButton_Click(object sender, RoutedEventArgs e)
  {
   setAppThemeTheme(ElementTheme.Dark);
  }
 }

Excellent! But what about retrieving Settings when user close the app and launch it again?

We have to check it in the App constructor when application is created first time:

 public App()
  {
  this.InitializeComponent();
  this.Suspending += OnSuspending;

  //Get reference to settings:
  var localSettings = ApplicationData.Current.LocalSettings;
  //Get saved theme value as string:
  var theme = localSettings.Values["AppTheme"].ToString();
  //Parse theme string value to ApplicationTheme enum value:
  var requestedTheme = (ApplicationTheme)Enum.Parse(typeof(ApplicationTheme), theme, true);
  //Apply selected theme for the app:
  RequestedTheme = requestedTheme;
  }

That’s all! Launch the app, try to change theme, close it and launch again. You should notice that App Theme is saved and restored each time:

UWPstorage4

 

4)Now you know how to use Settings to store and retrieve preferences for you UWP app. Now let’s see how to use Files to save some data:

When talking about storing data in files it is worth to mention three classess that we will use:

1. StorageFolder – class responsible for providing easy way to interact with folders through your app

2. StorageFile – class responsible for providing easy way to interact with files through your app

3. FileIO – class responsible for providing easy way write data into the files and read data from them

Below I will try to show how easily you can store the data in the files.

1. Let’s add TextBox, one more button and ListView to our UI. Why? We will try to save notes typed in the TextBox and display them on the ListView when app is launched again:

 <StackPanel Orientation="Vertical" HorizontalAlignment="Center" VerticalAlignment="Center">
 <Button x:Name="LightThemeButton" Content="Set light theme" Click="LightThemeButton_Click"/>
 <Button x:Name="DarkThemeButton" Content="Set dark theme" Click="DarkThemeButton_Click" Margin="0,10,0,0"/>
 <TextBox x:Name="NoteTextBox" PlaceholderText="Note..."/>
 <Button x:Name="SaveNoteButton" Content="Save note" Click="SaveNoteButton_Click" Margin="0,10,0,0" HorizontalAlignment="Stretch"/>
 </StackPanel>
 <ListView x:Name="NotesListView" VerticalAlignment="Bottom"/>

2. In the code behind we would like to handle notes and save them to the text file:

a. Firstly we need a collection to store our notes. Here I will use Observable collection that automatically notify ListView that new item was added to display it:

  ObservableCollection<string> _notes;
  public MainPage()
   {
    this.InitializeComponent();
    _notes = new ObservableCollection<string>();
    //Set data source for the ListView control:
    NotesListView.ItemsSource = _notes;
   }

b. To enable saving list with notes we need to serialize it to JSON format. Here we will use JSON .NET library from nuget. Right click on the project -> “Manage NuGet Packages…” and then try to search “Newtonsoft.Json”. After you click “Install” we are ready to go forward:

UWPstorage5

UWPstorage6

 

c. To add new note to the list we need to implement simple method shown below:

 private void addNoteToList()
  {
   _notes.Add(NoteTextBox.Text);
  }

 

d. Now we can serialize list with notes to JSON and save it in the text file:

 private async void saveNotes()
  {
   /* Firstly we will use StorageFolder class from the Windows.Storage namespace
   to get path to the LocalFolder for our application: */
   StorageFolder storageFolder = ApplicationData.Current.LocalFolder;

   /* Then we need to have reference to the file where we can store notes:
   Note that if file exists we do not want to create another one: */
   StorageFile notesFile = await storageFolder.CreateFileAsync("notes.txt", CreationCollisionOption.OpenIfExists);

   // Now we want to serialize list with the notes to save it in the JSON format ine the file:
   var serializedNotesList = JsonConvert.SerializeObject(_notes);

   // Last step is to write serialized list with notes to the text file:
   await FileIO.WriteTextAsync(notesFile, serializedNotesList);
  }

e. Just for this example I decided to split this operation on the two methods above. Now when you click “SaveButton” note will be displayed on the list and automatically whole list will be saved in the file:

 private void SaveNoteButton_Click(object sender, RoutedEventArgs e)
  {
   addNoteToList();
   saveNotes();
  }

Launch the app and add some notes. You should see them ath the bottom of the page:

UWPstorage7

Serialized note list was saved to the file but how we can retrieve it back when app is launched?

1. Add below method to the MainPage to retrieve notes list from the file:

  private async void retrieveNotes()
  {
   /* Firstly we will use StorageFolder class from the Windows.Storage namespace
   to get path to the LocalFolder for our application: */
   StorageFolder storageFolder = ApplicationData.Current.LocalFolder;

   /* Then we need to have reference to the file where we can store notes:
   Note that if file exists we do not want to create another one: */
   StorageFile notesFile = await storageFolder.CreateFileAsync("notes.txt", CreationCollisionOption.OpenIfExists);

   // Read serialized notes list from the file:
   string serializedNotesList = await FileIO.ReadTextAsync(notesFile);

   // Deserialize JSON list to the ObservableCollection:
   if(serializedNotesList!=null)
   {
   _notes = JsonConvert.DeserializeObject<ObservableCollection<string>>(serializedNotesList);
   NotesListView.ItemsSource = _notes;
   } 
  }

Invoke “retrieveNotes” method in the MainPage construstor:

  public MainPage()
  {
   this.InitializeComponent();
   _notes = new ObservableCollection<string>();
   NotesListView.ItemsSource = _notes;
   retrieveNotes();
  }

 

Launch the app again. Add some notes, close the app and re-launch it again. Your notes should still be there! 

UWPstorage8

Just to sum up I would you to know that you can easily save binary files (like pictures) with one step:

1. To save binary data:

await FileIO.WriteBytesAsync(yourBinaryFile, ImageArray);

2. To retrieve binary data:

var buffer = await FileIO.ReadBufferAsync(file);
using (MemoryStream mstream = new MemoryStream())
 {
  await buffer.AsStream().CopyToAsync(mstream);
  byte[] result = mstream.ToArray();
 }

Sum up

Now you know how to save user preferences in the Settings, you also have knowledge how to persist your data even if application is closed.

If you would like to read more about this topic please refere to this MSDN article.

Have fun!

Advertisements