【发布时间】:2019-08-04 19:13:02
【问题描述】:
我正在尝试实现一个 WPF 表单(显示员工数据),以便当任何字段发生更改时,头部标签 (FullnameTitle) 带有一个星号。例如。约翰·史密斯*
我正在使用 MVVM,其 ViewModel 基础还可以跟踪更改。我还选择将模型属性分开(即 NotifyPropertyChanged 在 ViewModel 中)
以下是我目前拥有的。我知道要更新头部标签,我需要在所有表单字段上调用 NotifyPropertyChanged("FullnameTitle")。
我的问题是,有没有更好的方法,不需要为每个领域都调用它? (我的完整员工表格有 50 多个字段)
窗口 XAML
<Label x:Name="HeadLabel" Content="{Binding FullnameTitle, FallbackValue='Employee Details'}" FontSize="28"/>
<StackPanel>
<Label Content="Employee ID"/>
<TextBox IsEnabled="False" Text="{Binding Employee.EmployeeId}"/>
<Label Content="First name"/>
<TextBox Text="{Binding Firstname, TargetNullValue=''}"/>
<Label Content="Surname"/>
<TextBox Text="{Binding Surname, TargetNullValue=''}"/>
<Label Content="DOB"/>
<DatePicker SelectedDate="{Binding Dob, TargetNullValue=''}"/>
<Label Content="Age"/>
<TextBox Text="{Binding Age, Mode=OneWay}" IsReadOnly="True"/>
</StackPanel>
视图模型
class EmployeeViewModel : ViewModelBase
{
public EmployeeModel Employee { get; set; }
public string FullnameTitle
{
get
{
return string.Format("{0} {1}{2}", Employee.Firstname, Employee.Surname, IsDirty ? "*" : "");
}
}
public string Firstname
{
get
{
return Employee.Firstname;
}
set
{
Employee.Firstname = ApplyPropertyChange(Employee.Firstname, value, "Firstname");
}
}
public string Surname
{
get
{
return Employee.Surname;
}
set
{
Employee.Surname = ApplyPropertyChange(Employee.Surname, value, "Surname");
}
}
public DateTime? Dob
{
get
{
return Employee.Dob;
}
set
{
Employee.Dob = ApplyPropertyChange(Employee.Dob, value, "Dob");
NotifyPropertyChanged("Age");
}
}
public int Age
{
get
{
return Employee.Age; // Age calculation done in EmployeeModel
}
}
}
ViewModelBase
abstract class ViewModelBase : INotifyPropertyChanged
{
public Dictionary<string, object> Changes { get; private set; }
public event PropertyChangedEventHandler PropertyChanged;
public ViewModelBase()
{
Changes = new Dictionary<string, object>();
}
public bool IsDirty
{
get { return Changes.Count > 0; }
}
public T ApplyPropertyChange<T>(T field, T value, string caller)
{
// Only do this if the value changes
if (field == null || !field.Equals(value))
{
string propertyName = caller; // Property name
field = value; // Set the value
Changes[propertyName] = value; // Change tracking
NotifyPropertyChanged(propertyName); // Notify change
}
return field;
}
public void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
【问题讨论】:
-
只有在属性发生更改时才会引发事件,不是吗?你有什么问题?
-
我想看看是否有比需要在每个绑定字段属性上添加
NotifyPropertyChanged("FullnameTitle")更好的方法。而且由于 FullnameTitle 标签只需要在第一个表单的字段值更改后更新...有没有办法只更新一次标签,并且仍然不需要在每个绑定字段属性上使用NotifyPropertyChanged("FullnameTitle")(包装在 if 语句中)跨度>