wpf 在MVVM Community Toolkit VM中,我加载一个Person(有20个可观察的 prop ),在V中我显示Person的数据,如何在任何数据更改时启用SaveButton?

xfb7svmp  于 11个月前  发布在  其他
关注(0)|答案(1)|浏览(102)

我有个模特

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])
}

字符串
视图模型如下所示
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);
    }
}


}
PersonView窗口包含几个控件(每个控件对应一个人的属性)和一个绑定到RelayCommand SaveCommand的SaveButton(最初禁用
我的问题是,当用户在这个窗口中更改Person的任何属性时,如何启用或禁用保存按钮。
由于我被卡住了,我找不到解决这个问题的办法。
如果Person包含2-3个属性,有一个解决方案,但是如果它包含很多属性,那么我就不能想出一个聪明的解决方案来避免重复的代码块
Thanks in advance

jjhzyzn0

jjhzyzn01#

方案一-使用数据库

根据我对数据库功能的理解,您可以将此任务委托给数据库,因为_db.ChangeTracker.HasChanges()可以检查是否有更改。因此,您可以将CanSaveChanges()更改为

private bool CanSaveChanges() => _db.ChangeTracker.HasChanges();

字符串

解决方案2 -使用PropertyChanged事件

否则,如果您的数据库无法检查更改,您可以使用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;
}

相关问题