我有模型
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])
}
视图模型如下
公共部分类 PatientViewModel : ObservableObject { 私人布尔_patentPropertyChanged = 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);
}
}
}
PersonView 窗口包含多个控件(一个用于每个人的属性)和一个最初禁用的 SaveButton,该按钮绑定到 RelayCommand SaveCommand
我的问题是,当用户在此窗口上更改任何人的属性时,如何启用或禁用保存按钮。
由于我陷入困境,我找不到这个问题的任何解决方案。
如果 Person 包含 2-3 个属性,有一个解决方案。但是当它包含很多时,我就无法想出一个聪明的解决方案来避免重复代码块
提前致谢
据我了解您数据库的功能,您可以将其委托给您的数据库,因为
_db.ChangeTracker.HasChanges()
接缝检查是否有更改。所以你可以将CanSaveChanges()
更改为
private bool CanSaveChanges() => _db.ChangeTracker.HasChanges();
否则,如果您的数据库无法检查更改,您可以使用 PropertyChanged 事件,例如:
// 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;
}
每当设置
CanExecuteChanged
属性时,您都应该引发该命令的 PatientPropertyChanged
事件。
在 MVVM 工具包中,您可以通过将
[NotifyCanExecuteChangedFor]
属性应用于属性的支持字段来完成此操作:
[ObservableProperty]
[NotifyCanExecuteChangedFor(nameof(SaveChangesCommand))]
private bool _patientPropertyChanged;