我有一个简单的WPF应用程序,我想知道为什么NotifyOfPropertyChange()不能按预期工作。我有一个具有两个属性和一个按钮的MainWindowViewModel,当我单击按钮时,我调用NotifyOfPropertyChange()来通知所有属性已更改。我还有一个在ViewModel构造函数中编译的属性列表:
properties = typeof(MainWindowViewModel).GetProperties()
.Where(p => p.DeclaringType == typeof(MainWindowViewModel));
在构造函数中,我已订阅PropertyChanged:
PropertyChanged += (sender, args) =>
{
if (properties.Any(p => p.Name == args.PropertyName))
IsDirty = true;
};
这是我的整个MainViewModel:
public class MainWindowViewModel : Screen
{
private string name;
private IEnumerable<PropertyInfo> properties;
public string Name
{
get { return name; }
set
{
name = value;
NotifyOfPropertyChange(() => Name);
}
}
private int age;
public int Age
{
get { return age; }
set
{
age = value;
NotifyOfPropertyChange(() => Age);
}
}
private bool isDirty;
public bool IsDirty
{
get { return isDirty; }
set
{
isDirty = value;
NotifyOfPropertyChange(() => IsDirty);
}
}
public MainWindowViewModel()
{
// get list of class properties
properties = typeof(MainWindowViewModel).GetProperties()
.Where(p => p.DeclaringType == typeof(MainWindowViewModel));
// if any property has been updated, set isDirty to true
PropertyChanged += (sender, args) =>
{
if (properties.Any(p => p.Name == args.PropertyName))
IsDirty = true;
};
}
public void Save()
{
NotifyOfPropertyChange();
}
}
当应用程序运行时,构造函数会正确生成属性列表:名称,年龄和IsDirty。但是,单击“保存”按钮后,
对于与 View 模型不相关的其他属性,引发PropertyChangedEvent:IsInitialized和IsActive,它们是屏幕的属性,对于列表中的任何属性都不引发。有人可以告诉我这是怎么回事还是提供替代解决方案?我认为我想做的很清楚,这是一个验证方案,如果单击保存按钮,则需要调用PropertyChanged并设置一个标志,以便可以验证所有属性。
最佳答案
NotifyOfPropertyChange()方法的方法签名为:
public virtual void NotifyOfPropertyChange([System.Runtime.CompilerServices.CallerMemberName] string propertyName = null)
(链接到Caliburn.Micro github存储库:https://github.com/Caliburn-Micro/Caliburn.Micro/blob/master/src/Caliburn.Micro/PropertyChangedBase.cs#L44)
注意
CallerMemberName
属性。从
Save
之类的NotifyOfPropertyChange();
方法中调用它会导致PropertyChanged事件,其PropertyChangedEventArgs.PropertyName设置为“Save”(调用NotifyOfPropertyChange()的方法的名称)。那当然没有道理。为了表明类中的任何属性已更改,您必须显式传递
null
或""
作为NotifyOfPropertyChange的参数(有效地绕过CallerMemberName替换):public void Save()
{
NotifyOfPropertyChange(null);
}
传递
null
或空字符串作为属性名称是有效的。没有属性名称的PropertyChanged事件表示任何一个或多个属性已更改其值。考虑到这一点,还应该改进PropertyChanged事件处理程序,以正确尊重没有属性名称的PropertyChanged事件:
PropertyChanged += (sender, args) =>
{
if (string.IsNullOrEmpty(args.PropertyName) || properties.Any(p => p.Name == args.PropertyName))
IsDirty = true;
};
关于c# - NotifyOfPropertyChange()通知 View 模型属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44334210/