C
C#2d 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;
}
}
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;
}
}
3 Replies
Anton
Anton2d ago
If you want other UI that depends on it to pick up the changes, you need it to be reactive. Otherwise, it doesn't matter when you create it. For all I care, you could create it when saving it
Zoli
ZoliOP23h ago
In a reactive approach for an edit operation, FooModel is passed to FooViewModel via the constructor. However, this means that any modifications made in the ViewModel will be directly reflected in the original model, even if the user cancels the operation without saving. How can I ensure that changes are only applied to the original model after a successful save operation while still leveraging reactivity? What is the best practice for maintaining the original state if the user decides to discard the changes?
Anton
Anton21h ago
I mean, just do the most logical thing Work with a copy on that page Apply it to the original model when you save Which is what what you're doing I think

Did you find this page helpful?