NotifyOfPropertyChange() 没有通知视图模型属性
NotifyOfPropertyChange() is not notifying viewmodel properties
我有一个简单的 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();
}
}
应用程序运行时,构造函数会正确生成属性列表:Name、Age 和 IsDirty。但是,当单击保存按钮时,
PropertyChangedEvent 是针对与视图模型无关的其他属性引发的:IsInitialized 和 IsActive,它们是屏幕的属性,并且不会针对列表中的任何属性引发。有人可以告诉我这里发生了什么或提供替代解决方案吗?我想我想做什么很清楚,这是一个验证场景,如果单击保存按钮,我需要调用 PropertyChanged 并设置一个标志,以便验证所有属性。
NotifyOfPropertyChange() 方法的方法签名是:
public virtual void NotifyOfPropertyChange([System.Runtime.CompilerServices.CallerMemberName] string propertyName = null)
(Link 到 Caliburn.Micro github 存储库:https://github.com/Caliburn-Micro/Caliburn.Micro/blob/master/src/Caliburn.Micro/PropertyChangedBase.cs#L44)
注意 CallerMemberName
属性。
从 Save
方法中调用它,如 NotifyOfPropertyChange();
将导致带有 PropertyChangedEventArgs.PropertyName 的 PropertyChanged 事件 设置为 "Save"(调用 NotifyOfPropertyChange() 的方法的名称)。那当然没有意义。
要表明 class 中的任何 属性 已更改,您必须显式传递 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;
};
我有一个简单的 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();
}
}
应用程序运行时,构造函数会正确生成属性列表:Name、Age 和 IsDirty。但是,当单击保存按钮时, PropertyChangedEvent 是针对与视图模型无关的其他属性引发的:IsInitialized 和 IsActive,它们是屏幕的属性,并且不会针对列表中的任何属性引发。有人可以告诉我这里发生了什么或提供替代解决方案吗?我想我想做什么很清楚,这是一个验证场景,如果单击保存按钮,我需要调用 PropertyChanged 并设置一个标志,以便验证所有属性。
NotifyOfPropertyChange() 方法的方法签名是:
public virtual void NotifyOfPropertyChange([System.Runtime.CompilerServices.CallerMemberName] string propertyName = null)
(Link 到 Caliburn.Micro github 存储库:https://github.com/Caliburn-Micro/Caliburn.Micro/blob/master/src/Caliburn.Micro/PropertyChangedBase.cs#L44)
注意 CallerMemberName
属性。
从 Save
方法中调用它,如 NotifyOfPropertyChange();
将导致带有 PropertyChangedEventArgs.PropertyName 的 PropertyChanged 事件 设置为 "Save"(调用 NotifyOfPropertyChange() 的方法的名称)。那当然没有意义。
要表明 class 中的任何 属性 已更改,您必须显式传递 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;
};