Roaming Application Data in Windows Store App Using C#

Today we are going to  learn how to store and retrieve data from the Roaming application data storage in Windows 8 Apps. In my previous article we learned about the Temporary Application data location in Windows 8 Apps.

Sometimes when the user's apps are installed on multiple devices, the user needs to keep their data in a Roaming location. For that you need to use Roaming data in your app. By using Roaming Application Data Storage the user is able to store their application data across multiple device or locations. The data is then synchronized among multiple devices. Windows enables the user to replicate the data kept in the roaming locations and automatically updates the other devices where the user's application is installed.

The the size of the data stored in a Roaming location is limited for each application. The user cannot Roam with a large amount of data. If the size of the data exceeds the limit specified for storing the data then  Windows does not replicate application data to the cloud.

I suggest you do not to store large size files to the Roaming Application Data. Use Roaming Application Data to keep as small amout of information as possible like small links, URL, small data files etc.

The data in Roaming Application data can change any time. You should perform some necessary task whenever application data is changed.

Now, we are trying to save user data to Roaming Application data storage and also retrieve from it. So, now we proceed to create a Windows 8 Store blank application and data to Roaming Application data storage.

Step 1

First create a Blank Application using C# and XAML.

Step 2

First of all we need to register for the data changed event, so that we receive updated data when data gets changed to the roaming devices; see:

public LandingPage()

{

   this.InitializeComponent();
   Windows.Storage.ApplicationData.Current.DataChanged +=

   new TypedEventHandler<ApplicationData, object>(DataChangeHandler);
}
 

void DataChangeHandler(Windows.Storage.ApplicationData appData, object o)

{

   // TODO: Refresh your data

}

Step 3

I've created a simple blank XAML page:

<Page

    x:Class="savinguserdataonsuspended.MainPage"

    IsTabStop="false"

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    xmlns:local="using:savinguserdataonsuspended"

    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

    mc:Ignorable="d">

 

    <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">

        <Canvas>

            <TextBox Canvas.Left="249.977" TextWrapping="Wrap" Canvas.Top="67.89" x:Name="IdTextBox" 
                 RenderTransformOrigin="0.5,0.5" UseLayoutRounding="False" Width="259.477"
                 d:LayoutRounding="Auto"/>                      

            <TextBlock Canvas.Left="90" FontSize="30" TextWrapping="Wrap" Text="Email ID"
            Canvas.Top="75"/>

            <TextBox Canvas.Left="250" TextWrapping="Wrap" Canvas.Top="130" x:Name="NameTextBox" 
           Width="261"/>

            <TextBlock Canvas.Left="85" TextWrapping="Wrap" Text="Name" FontSize="30" Canvas.Top="129"/>

            <Button x:Name="save" Content="Login" Click="save_Click_1" FontSize="25"  Canvas.Top="210" 
             Canvas.Left="187" Height="62" Width="154"></Button>

        </Canvas>

    </Grid>

</Page>

Step 4


Now, I need an entity for the values of these controls and then save the entire bucket to Roaming Application Storage. So, I'm going to create a UserDetails class; see:
 

public class UserDetail

{

    public int Id { getset; }

    public string Name { getset; }

    public bool HasValue { getset; }

}

Step 5

I use the Button's click events to keep the instance of UserDetails updated and call a SaveAsync() method and then, navigate to another page; see:

private async void login_Click_1(object sender, RoutedEventArgs e)

{

     Stats.Name = NameTextBox.Text;

     Stats.Id = int.Parse(IdTextBox.Text);

     SaaveAsync();

     this.Frame.Navigate(typeof(LandingPage));                 
}

You all know that everything in Windows 8 Store apps is asynchronous, so we'll see the async and await keywords in these apps.

 

Step 6

You have to include the Namespace to access the Storage location of Application data.

Using Window.Storage;

Using Window.Storage.Streams;

Step 7

In the SaveAsync method we will serialize the data to be saved into Roaming Application Storage.
 

StorageFile userdetailsfile = await ApplicationData.Current.RoamingFolder.CreateFileAsync("UserDetails",

 CreationCollisionOption.ReplaceExisting);            

IRandomAccessStream raStream = await userdetailsfile.OpenAsync(FileAccessMode.ReadWrite);

using (IOutputStream outStream = raStream.GetOutputStreamAt(0))

{

    // Serialize the Session State.

    DataContractSerializer serializer = new DataContractSerializer(typeof(UserDetails));

    serializer.WriteObject(outStream.AsStreamForWrite(), Stats);

    await outStream.FlushAsync();

}

In the preceding code first we get the Roaming folder of Temporary storage and then create a file using the CreateFileAsync() method also use the parameter ReplaceExisting if the file already exists. Then we open it using OpenAsync in the read/write mode. Then I serialize the object using the DataContractSerializer class and write this serializer obect to a file using the WriteObject method.

Step 8

In the Next Page where we naviagte after login we call the ReterieveAsync() method to restore the value back to a bucket at the OnNavigatedTo event of the page.
 

protected async override void OnNavigatedTo(NavigationEventArgs e)

{

RestoreAsync();
}
 

Step 9

Here is the code of the ReterieveAsync() method where I read the file from the Roaming Folder, deserialize it's contents and then set the instance of UserDetails with the values that were saved earlier.

{
StorageFile file = await ApplicationData.Current.RoamingFolder..GetFileAsync("UserDetails");    
if (file == nullreturn;
IRandomAccessStream inStream = await file.OpenReadAsync();                       
    // Deserialize the Session State.
DataContractSerializer serializer = new DataContractSerializer(typeof(UserDetails));
var name = (UserDetails)serializer.ReadObject(inStream.AsStreamForRead());
inStream.Dispose();          
UserName.Text ="Welcome "+Stats.Name;
UserProfileId = Stats.Id;
}

We can also delete or remove the files as required from the Roaming Application Data Store.


Similar Articles