There are multiple ways to do this out there, this is a basic example of how to approach the idea. You are basically asking "How do I keep track of the fact that at least one of my properties has changed, and how do I revert it if the user decides against saving".
For your current example, you could add a flag in your class that also gets updated any time a property gets updated.
See this:
private int id;
public int Id {
get => id;
set
{
HasChanged = true;
id = value;
}
}
public bool HasChanged = false;
Then if the user tries to navigate away, you can check the boolean to see if it needs to be interrupted and decide if you need to restore data.
There are many ways to do this, this is just one example of how you could start to implement it. It's a very common approach in MVVM to have a view model with a dirty flag that can reset if the user chooses. Here is another example on StackOverflow that could help you: MVVM - implementing 'IsDirty' functionality to a ModelView in order to save data
To further build on this, I will show you an example of a base class I use for some of my work and how I implement an IsDirty
flag, to indicate if any of my information has changed.
Here is my BaseViewModel
:
public class BaseViewModel : INotifyPropertyChanged
{
protected bool isDirty = false;
public bool IsDirty
{
get { return isDirty; }
set { SetProperty(ref isDirty, value); }
}
protected bool isBusy = false;
public bool IsBusy
{
get { return isBusy; }
set { SetProperty(ref isBusy, value); }
}
protected string title = string.Empty;
public string Title
{
get { return title; }
set { SetProperty(ref title, value); }
}
protected bool SetProperty<T>(ref T backingStore, T value,
[CallerMemberName] string propertyName = "",
Action onChanged = null)
{
if (EqualityComparer<T>.Default.Equals(backingStore, value))
return false;
backingStore = value;
onChanged?.Invoke();
OnPropertyChanged(propertyName);
// if the property actually changed, IsDirty is true => used to determine if saving is needed
if (propertyName != nameof(IsDirty) && propertyName != nameof(IsBusy))
{
IsDirty = true;
}
return true;
}
#region INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string propertyName = "")
{
var changed = PropertyChanged;
if (changed == null)
return;
changed.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
}
And here is an example of an ItemDetailViewModel
(mostly autogenerated from Microsoft) which implements that BaseViewModel
:
public class ItemDetailViewModel : BaseViewModel
{
private string itemId;
private string text;
private string description;
public string Id { get; set; }
public string Text
{
get => text;
set => SetProperty(ref text, value);
}
public string Description
{
get => description;
set => SetProperty(ref description, value);
}
public string ItemId
{
get
{
return itemId;
}
set
{
itemId = value;
LoadItemId(value);
}
}
public async void LoadItemId(string itemId)
{
IsBusy = true;
try
{
var item = await DataStore.GetItemAsync(itemId);
Id = item.Id;
Text = item.Text;
Description = item.Description;
}
catch (Exception)
{
Debug.WriteLine("Failed to Load Item");
}
finally
{
IsBusy = false;
IsDirty = false;
}
}
Now, if any of my ItemDetailViewModel
objects ever have a property modified, that specific object's IsDirty
flag would be set to true
until I set it back to false
. Notice in this example, I actually have an item
that gets loaded, and I copy those properties into a "View Model" of that item
. Ultimately, when I go to save, I will check to see if the view model is dirty, and if so, I would then update the existing item
.
Perhaps implementing something like this in your project would help you. It may add to the amount of code you are writing when it comes to the property setting, but ultimately you may find it helps with managing the objects.