C#C
C#10mo ago
Zoli

How to Properly Synchronize ViewModel and Model in MVVM (CommunityToolkit.Mvvm)

I'm working with an MVVM pattern using CommunityToolkit.Mvvm and have a FooModel and corresponding FooViewModel. When saving, I need to ensure that the ViewModel updates the Model correctly.
I currently instantiate the model inside the ViewModel and update it when properties change. However, I'm unsure whether the model should be automatically updated as the ViewModel changes, or if I should create a new model object when saving?

public class FooModel
{
    public int Property { get; set; }
    public List<SubFooModel> SubFooModels { get; set; } = [];

    public SubFooModel AddSubFoo()
    {
        var model = new SubFooModel();
        SubFooModels.Add(model);
        return subFooModel;
    }
}

public class SubFooModel
{
    public int Property { get; set; }
}

public partial class FooViewModel : ObservableObject
{
    private readonly FooModel _model;

    [ObservableProperty]
    private int _property;

    public ObservableCollection<SubFooViewModel> SubFooViewModels { get; private set; } = [];

    partial void OnPropertyChanged(int value)
    {
        _model.FooProperty = value;
    }

    public FooViewModel()
    {
        _model = new FooModel();
        Property = _model.FooProperty;
        SubFooViewModels = new ObservableCollection<SubFooViewModel>(
             _model.SubFooModels.Select(sub => new SubFooViewModel(sub))
        );
    }

    [RelayCommand]
    private void AddSubFoo()
    {
        var subFoo = _model.AddSubFoo();
        SubFooViewModels.Add(new SubFooViewModel(subFoo));
    }

    [RelayCommand]
    private void Save()
    {
        //Repo.Save(_model);
    }
}

public partial class SubFooViewModel : ObservableObject
{
    private readonly SubFooModel _model;

    [ObservableProperty]
    private int _property;

    partial void OnPropertyChanged(int value)
    {
        _model.Property = value;
    }

    public SubFooViewModel(SubFooModel model)
    {
        _model = model;
        Property = _model.Property;
    }
}
Was this page helpful?