2

So I'm not sure if it is correct for me to ask this, but I've been self learning WPF and I can't figure out a method to save the data the user enters in my application.

Let's say a project requires the user to input a IList<int> of values. So I have a class storing that information. This information can be loaded from a json filed if the user has already input it and saved within the application.

public class Vault : BindableBase
{

    public Vault(string savedFilePath = null)
    {
        if (string.IsNullOrEmpty(savedFilePath))
        {
            Measures = new List<int> { 1, 2, 3, 4 };
        }
        else
        {
            Measures = (List<int>)JsonConverter.DeserializeObject<List<int>>(savedFilePath);
        }
    }

    public IList<int> Measures { get; set; }
}

Now, when I create the application view, I want to load all the ViewModels the user will use. In each ViewModel, an element of the Measures List must go.

public MainWindowViewModel()
{
    vault = new Vault(savedFilePath);

    Collection = new ObservableCollection<object>
    {
        new FirstViewViewModel(vault.Measures[0]),
        new SecondViewViewModel(vault.Measures[1])
    };

}

So that when I press Save, the Vault class can be serialized.

public void Save()
{
   File.WriteAllText(fileLocation, JsonConvert.SerializeObject(vault));
}

As I want to modify the values in Vault with the user input, I need a direct reference to it, therefore in the ViewModels what I do is

public class FirstViewViewModel : BindableBase
{
    private int _measure;

    public FirstViewViewModel(int measure)
    {
        _measure = measure;
    }

    public int Measure
    {
        get => _measure;
        set => SetProperty(ref _measure, value);
    }

}

Nevertheless this seems an awful way to connect the user input with the data i want to save in a file.

This is a simplified case of what I want to achieve. However I am sure there are a better way that would allow me to change the values in Vault when Raising a property on the ViewModel. Ideally one that would make UnitTest easy (I haven't started with that yet).

If anyone could offer me a clue to find a better method to deal with this kind of situation, I would really appreciate it.

Albert Alonso
  • 656
  • 1
  • 6
  • 21

1 Answers1

3

This will probably get flagged for being too broad in scope, but in general you should serialize the data to a database. This article is a great place to start:

https://learn.microsoft.com/en-us/ef/ef6/modeling/code-first/workflows/new-database

If your data structures are very lite then you might want to use something like SQLite, which stores the database in a local file and doesn't require installing any 3rd-party applications along with your application. Plenty of info here on how to get that working with Entity Framework:

Entity Framework 6 with SQLite 3 Code First - Won't create tables

Mark Feldman
  • 15,731
  • 3
  • 31
  • 58
  • 1
    I'd suggest EF Core for a new app... but definitely the way to go (unless the data is _really_ trivial). Also, one could add that EF should be hidden in a service instead of being accessed directly in each view model. – Haukinger May 11 '19 at 19:06