繁体   English   中英

当其他 TextBox 更改时,WPF 绑定的 TextBox 值不会更新

[英]WPF Bound TextBox value not updating when other TextBox is changed

我有一个 WPF 窗口,允许用户编辑员工的出生日期,在此窗口中还有一个文本框,用于显示输入的 DoB 的年龄。

DoB 文本框绑定到我的 EmployeeModel Dob 属性

Age 文本框绑定到我的 EmployeeModel Age 属性并且无法设置,并且使用 Dob 值获取。

我面临的问题是当用户更改 DoB 时,年龄文本框不会更新。

我发现如果我在我的 EmployeeModel 中实现INotifyPropertyChanged ,并在 Dob 属性中添加OnPropertyChanged("Age") ,那么 Age 值就会更新。 但这违背了我的建议,我的模型应该只是业务逻辑,而不应该实现 INotifyPropertyChanged。

我应该如何设置它以便在不修改模型的情况下更改 DoB 时更新年龄?


员工模型

class EmployeeModel
{
    public DateTime? Dob { get => _dob; set => _dob = value; }
    public int Age
    {
        get
        {
            if (_dob == null)
                return 0;

            DateTime now = DateTime.Today;
            int age = now.Year - _dob.Value.Year;
            if (now < _dob.Value.AddYears(age))
                age--;

            return age;
        }
    }
}

员工视图模型

class EmployeeViewModel : INotifyPropertyChanged
{
    private EmployeeModel _employee;

    public EmployeeModel Employee
    {
        get => _employee;
        set
        {
            if (_employee != value)
            {
                _employee = value;
                OnPropertyChanged();
            }
        }
    }
    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged([System.Runtime.CompilerServices.CallerMemberName]string caller = null)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(caller));
    }

看法

<Label Content="DOB" />
<DatePicker SelectedDate="{Binding Employee.Dob, TargetNullValue=''}" />
<Label Content="Age" />
<TextBox Text="{Binding Employee.Age, Mode=OneWay}" />

如果您不想在EmployeeModel实现INotifyPropertyChanged ,则不应绑定到EmployeeModel的属性,而是绑定到在EmployeeModel中包装该属性的视图模型的属性,例如:

class EmployeeViewModel : INotifyPropertyChanged
{
    private EmployeeModel _employee;

    public DateTime? Dob
    {
        get { return _employee.Dob; }
        set { _employee.Dob = value; OnPropertyChanged(); OnPropertyChanged(nameof(Age)); }
    }

    public int Age
    {
        get { return _employee.Age; }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged([System.Runtime.CompilerServices.CallerMemberName]string caller = null)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(caller));
    }
}

XAML:

<Label Content="DOB" />
<DatePicker SelectedDate="{Binding Dob, TargetNullValue=''}" />
<Label Content="Age" />
<TextBox Text="{Binding Age, Mode=OneWay}" />

我也在用你的方法来计算年龄,它工作正常。

我有一个在单独的类中定义的患者模型

这是视图模型:

class PatientRecordDetailsViewModel : INotifyPropertyChanged
{
    public DateTime PatientDateOfBirth
    {
        get => m_patientDateofbirth;
        set
        {
            m_patientDateofbirth = value;
            OnPropertyChange("PatientDateOfBirth");
            OnPropertyChange(nameof(PatientAge));
        }
    }

    public int PatientAge => CalculateAge();

    private int CalculateAge()
    {
        if (m_patientDateofbirth == null)
        {
            return 0;
        }
        else
        {
            int CurrentYear = DateTime.Now.Year;
            int BirthYear = m_patientDateofbirth.Year;
            m_patientAge = CurrentYear - BirthYear;
            return m_patientAge;
        }           
    }

    public event PropertyChangedEventHandler PropertyChanged;
     private void OnPropertyChange(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

这是 Xaml

<DatePicker Name="Date" Grid.Column="0" SelectedDate ="{Binding Path = PatientDateOfBirth, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource DatePickerStyle}" VerticalAlignment="Center" Height="30" Padding="3,0,5,0"/>
<TextBox  Name="Age" Grid.Column="1" Text="{Binding Path = PatientAge, Mode=OneWay}" Style="{StaticResource TextBoxStyle}"/>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM