我有一个WPF窗口,允许用户编辑员工的出生日期,在该窗口中还有一个文本框,用于显示输入的DoB的年龄。
DoB文本框绑定到我的EmployeeModel Dob属性
年龄文本框绑定到我的EmployeeModel年龄属性,无法设置,并且获取使用Dob值。
我面临的问题是,当用户更改DoB时,“年龄”文本框没有更新。
我发现,如果我在EmployeeModel中实现INotifyPropertyChanged
,并在Dob属性中添加OnPropertyChanged("Age")
,那么Age值将得到更新。但这违背了我的建议,我的模型应该仅是业务逻辑,而不应实现INotifyPropertyChanged。
我应该如何设置以便在更改DoB时不修改模型就更新Age?
EmployeeModel
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;
}
}
}
EmployeeViewModel
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}" />
答案 0 :(得分:0)
如果您不想在INotifyPropertyChanged
中实现EmployeeModel
,则不应绑定到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}" />
答案 1 :(得分:0)
我也正在使用您的方法来计算年龄,并且可以正常工作。
我有一个在单独的类中定义的Patient模型
这是ViewModel:
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}"/>