【发布时间】:2016-08-12 10:10:49
【问题描述】:
我正在用 c# WPF 开发一个应用程序。
我使用一个类 PropertyChangedNotifier 来管理 INotifyPropertyChanged(请参阅 that link)。
我使用经典的 ViewModelBase :
public class ViewModelBase : INotifyPropertyChanged, IRequestClose
{
public PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = _propertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
在我的MainViewModel : ViewModelBase 我有一个PropertyChangedNotifier<MainViewModel> 像这样工作:
class MainViewModel : ViewModelBase
{
private PropertyChangedNotifier<MainViewModel> _notifier;
public new event PropertyChangedEventHandler PropertyChanged
{
add { _notifier.PropertyChanged += value; }
remove { _notifier.PropertyChanged -= value; }
}
public MainViewModel()
{
_notifier = new PropertyChangedNotifier<MainViewModel>(this);
}
protected new void OnPropertyChanged(string propertyName)
{
_notifier.OnPropertyChanged(propertyName);
}
}
但未检测到更改,当值更改时,我的 MainWindows 不会刷新(不使用 PropertyChangedNotifier 它可以工作)。我看到系统使用WindowsBase.dll!System.ComponentModel.PropertyChangedEventManager.StartListening(object source) 启动窗口,然后我看到调用 MainViewModel 的构造函数时我的 ViewModelBase.PropertyChanged 不为空。
有没有可能做这样的事情:
public MainViewModel()
{
_notifier = new PropertyChangedNotifier<MainViewModel>(this);
_notifier.PropertyChanged = base.PropertyChanged;
}
那会修复我的错误吗?
编辑:
来自链接的PropertyChangeNotifier:
[AttributeUsage( AttributeTargets.Property )]
public class DepondsOnAttribute : Attribute
{
public DepondsOnAttribute( string name )
{
Name = name;
}
public string Name { get; }
}
public class PropertyChangedNotifier<T> : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public PropertyChangedNotifier( T owner )
{
mOwner = owner;
}
public void OnPropertyChanged( string propertyName )
{
var handler = PropertyChanged;
if( handler != null ) handler( mOwner, new PropertyChangedEventArgs( propertyName ) );
List<string> dependents;
if( smPropertyDependencies.TryGetValue( propertyName, out dependents ) )
{
foreach( var dependent in dependents ) OnPropertyChanged( dependent );
}
}
static PropertyChangedNotifier()
{
foreach( var property in typeof( T ).GetProperties() )
{
var dependsOn = property.GetCustomAttributes( true )
.OfType<DepondsOnAttribute>()
.Select( attribute => attribute.Name );
foreach( var dependency in dependsOn )
{
List<string> list;
if( !smPropertyDependencies.TryGetValue( dependency, out list ) )
{
list = new List<string>();
smPropertyDependencies.Add( dependency, list );
}
if (property.Name == dependency)
throw new ApplicationException(String.Format("Property {0} of {1} cannot depends of itself", dependency, typeof(T).ToString()));
list.Add( property.Name );
}
}
}
private static readonly Dictionary<string, List<string>> smPropertyDependencies = new Dictionary<string, List<string>>();
private readonly T mOwner;
}
【问题讨论】:
-
PropertyChangedNotifier<T>的目的是什么?为什么不简单地自己正确实现INotifyPropertyChanged? -
@LasseV.Karlsen 特别是当它已经通过从 ViewModelBase 继承实现时。 IMO,这个问题没有意义。
-
PropertyChangedNotifier 用于创建属性之间的依赖关系。如果我创建一个具有高度、宽度和周长的正方形,我可以在属性周长上设置
[DependsOn("height")]。像这样,当高度发生变化时,我的 PropertyChangedNotifier 将引发周长和高度的属性变化。 -
但是你没有暴露那个通知器?公开你只是公开你的 INotifyPropertyChanged 的实现,你为什么需要通知类?
-
通知器在链接中(见第 2 行)。我的问题是:如何从上层类中复制 EventHandler ?
标签: c# wpf inotifypropertychanged