0

After studying the manual of Visual C#, I'm starting to program a simple app for Windows 8. I'm using Visual Studio 2013 Express and .NET Framework 4.5.1. In the code I've written up to now, in the code-behind of a page I create a list of people:

private Dictionary<string, People> listPeople = new Dictionary<string, People>();

After this, I wish this list would fill a ComboBox control of another page. The solution I thought is to save the Dictionary<string, People> variable in roaming, and then use it where I need. In this way also would solve the problem of maintaining the list of people saved even when the app is terminated.

How can I do?

Marco87
  • 13
  • 4
  • I've not experience with win 8.1 apps, but i think that, to mantain the list available also if the app is terminated, you need to serialize it in a physical file, XML for example. – Stefano Bafaro Nov 19 '13 at 15:07
  • A `Dictionary` is not a `List`. Be careful with that distinction! Please define roaming. What documentation references this action? – Gusdor Nov 19 '13 at 15:07
  • @StefanoBafaro How I can do this? – Marco87 Nov 20 '13 at 11:04
  • @Gusdor Ok, I'm sorry. I know that `List` and `Dictionary` aren't the same thing. With "roaming" I'm refering at Windows.Storage.ApplicationData.Current.RoamingSettings. I would like to do something very similar to what is shown in step 2 (see point 6), [here](http://msdn.microsoft.com/en-us/library/windows/apps/hh986968.aspx). Can I do something similar with `Dictionary`? – Marco87 Nov 20 '13 at 11:07
  • @Marco87 You have to use a XmlSerializer. Loop through your data collection, adapt it with the Xml attributes, and then save it. Look at this post where they explain it: http://stackoverflow.com/questions/12554186/how-to-serialize-deserialize-to-dictionaryint-string-from-custom-xml-not-us – Stefano Bafaro Nov 20 '13 at 11:07
  • @StefanoBafaro Thanks for the reply. However, the proposed code does not seem to work for Windows 8.1 app that I'm realizing. In addition, the variable `listPeople` must be available from any device that the user owns and on which installs the app. For this I would use the solution to save data roaming, similarly at that it's done [here](http://msdn.microsoft.com/en-us/library/windows/apps/hh986968.aspx) in step 2. – Marco87 Nov 20 '13 at 15:44

2 Answers2

0

did you already try it like that?

var applicationData = Windows.Storage.ApplicationData.Current;
applicationData.RoamingSettings.Values["PeopleList"] = listPeople;

var applicationData = Windows.Storage.ApplicationData.Current;
var listPeople = (Dictionary<string, People>)applicationData.RoamingSettings.Values["PeopleList"];
Jan Rothkegel
  • 737
  • 3
  • 21
0

The overwhelming advice is to serialize your setting as a string then set the value in Values (or save the values in the complex type individually).

But, I think that really ignores the fact that Values is a series of key-value pairs... If you want to support complex types, I think creating your own file in the roaming folder is a better idea. I've written a small helper class to accomplish this via JSON serialization:

public class ApplicationStorageHelper
{
    private static readonly JsonSerializer jsonSerializer = JsonSerializer.Create();

    public static async Task<bool> SaveData<T>(T data)
    {
        var file =
            await ApplicationData.Current.RoamingFolder.CreateFileAsync("settings.dat", CreationCollisionOption.ReplaceExisting);
        using (var stream = await file.OpenAsync(FileAccessMode.ReadWrite))
        {
            using (var outputStream = stream.GetOutputStreamAt(0))
            {
                using (var writer = new StreamWriter(outputStream.AsStreamForWrite()))
                {
                    var jsonWriter = new JsonTextWriter(writer);
                    jsonSerializer.Serialize(jsonWriter, data);
                    return true;
                }
            }
        }
    }

    public static async Task<T> LoadData<T>()
    {
        try
        {

            var file =
                await ApplicationData.Current.RoamingFolder.GetFileAsync("settings.dat");
            using (var inputStream = await file.OpenSequentialReadAsync())
            {
                using (var reader = new StreamReader(inputStream.AsStreamForRead()))
                {
                    var jsonReader = new JsonTextReader(reader);
                    return jsonSerializer.Deserialize<T>(jsonReader);
                }
            }
        }
        catch (FileNotFoundException)
        {
            return default(T);
        }
    }
}

You'll have to reference JSON.Net from Nuget or some other way.

Peter Ritchie
  • 35,463
  • 9
  • 80
  • 98
  • Peter, thank you very much! But `ApplicationData,` `CreationCollisionOption` and `FileAccessMode` not exist in the current context. Missing something in the code that you wrote? Also, once written this class, how to use it to save `listPeople` roaming? – Marco87 Dec 03 '13 at 10:13
  • Ok, I found that there were no directives: `using Newtonsoft.Json;` and `using Windows.Storage;.` But, now, how to save `listPeople`? And how do you recover `listPeople` saved? Thank you. – Marco87 Dec 15 '13 at 13:23
  • Call SaveData to save data and LoadData to load data. – Peter Ritchie Dec 15 '13 at 23:00