I have a model
public partial class Patient : GenericEntity
{
[ObservableProperty]
private int genderId;
[ObservableProperty]
[NotifyPropertyChangedFor(nameof(Crucials))]
private string lastName = string.Empty;
[ObservableProperty]
[NotifyPropertyChangedFor(nameof(Crucials))]
private string firstName = string.Empty;
[ObservableProperty]
private string fatherName = string.Empty;
[ObservableProperty]
[NotifyPropertyChangedFor(nameof(Crucials))]
[NotifyPropertyChangedFor(nameof(Age))]
private DateTime _DOB = DateTime.Now;
[NotMapped]
public int Age
{
get
{
//DateOnly currentDate = DateOnly.FromDateTime(DateTime.Now);
DateTime currentDate =DateTime.Now;
int age = currentDate.Year - DOB.Year;
// Check if the current date is before the birth date
if (currentDate < DOB.AddYears(age))
{
age--;
}
return age;
}
}
[ObservableProperty]
private string _address = "";
[ObservableProperty]
private string _city = "";
[ObservableProperty]
private string _country = "";
[ObservableProperty]
private string _tel1 = "";
[ObservableProperty]
private string _tel2 = "";
[ObservableProperty]
private string _email = "";
//(15 more fields are following all of them decorated with [ObservableProperty])
}
The viewmodel is as follows
public partial class PatientViewModel : ObservableObject { private bool _patientPropertyChanged = false;
private AppDbContext _db;
private readonly PatientRepository _patientRepository;
private readonly NATreeNodeRepository _natreenodeRepository;
private Patient? patient;
[ObservableProperty]
private int _patientId = 0;
[RelayCommand(CanExecute = nameof(CanSaveChanges), IncludeCancelCommand = true)]
private async Task SaveChanges(CancellationToken token)
{
var hasChanges = _db.ChangeTracker.HasChanges();
if (hasChanges)
{
try
{
// Update the Patient's registration date to DateTime.Now
if (Patient != null)
{
Patient.UpdatedOn = DateTime.Now;
}
await _db.SaveChangesAsync();
MessageBox.Show("Changes successfully saved to the database!");
}
catch (System.Exception ex)
{
MessageBox.Show(ex.Message);
}
}
MessageBox.Show("Saved changes");
}
}
private bool CanSaveChanges() => PatientPropertyChanged;
public PatientViewModel(int patientId)
{
_db = new();
_patientRepository = new PatientRepository(_db);
_natreenodeRepository = new NATreeNodeRepository(_db);
PatientId = patientId;
InitializeAsync(PatientId);
_patientPropertyChanged = false;
}
private async void InitializeAsync(int patientId)
{
try
{
// Retrieve the patient with the given ID from the repository
Patient = await Task.Run(() => _patientRepository.Get(patientId)); // Replace with your repository method
// Check if patient is null or doesn't exist
if (Patient == null)
{
Patient = new()
{
};
_patientRepository.Add(Patient);
}
}
catch (Exception ex)
{
Debug.WriteLine("Error: " + ex.Message);
}
}
}
The PersonView window contains several controls (one for each of the person's properties) and a, initially disabled, SaveButton bound to a RelayCommand SaveCommand
My question is how can someone enable or disable the save button when any of the Person's properties is changed by the user on this window.
As I am stuck I can not find any solution to this question.
There is a solution if the Person contains 2-3 properties. But when it contains many then I can not come up with a clever solution that could avoid repeating blocks of code
Thanks in advance
As I understand the capabilities of you Database you may delegate this to your database, as _db.ChangeTracker.HasChanges()
seams to check if there are changes. So you may change CanSaveChanges()
to
private bool CanSaveChanges() => _db.ChangeTracker.HasChanges();
Otherwise if you database can not check for changes this you may use the PropertyChanged Event like:
// Properties for Patient and Changed State
[ObservableProperty] private bool _patientPropertyChanged;
[ObservableProperty] private Patient _patient;
public bool CanSaveChanges() => PatientPropertyChanged;
private async void InitializeAsync(int patientId)
{
try
{
if (Patient == null)
{
Patient = new()
{
};
_patientRepository.Add(Patient);
}
//Add Event Handle to set changed
Patient.PropertyChanged += (s, e) =>
{
//You may filter here for relevant changes
PatientPropertyChanged = true;
};
}
catch (Exception ex)
{
Debug.WriteLine("Error: " + ex.Message);
}
}
[RelayCommand(CanExecute = nameof(CanSaveChanges), IncludeCancelCommand = true)]
private async Task SaveChanges(CancellationToken token)
{
var hasChanges = _db.ChangeTracker.HasChanges();
if (hasChanges)
{
//..
}
//Reset changed Satte
PatientPropertyChanged = false;
}