在继承类中复制EventHandler



我正在用c# WPF开发一个应用程序。

我使用一个类PropertyChangedNotifier来管理INotifyPropertyChanged(见该链接)。

我使用经典的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不刷新(不使用propertychangednotification它工作)。我看到系统通过使用WindowsBase.dll!System.ComponentModel.PropertyChangedEventManager.StartListening(object source)启动窗口,然后我看到我的ViewModelBase。当调用MainViewModel的构造函数时,PropertyChanged不为空。

是否有可能做出这样的东西:

public MainViewModel()
{
    _notifier = new PropertyChangedNotifier<MainViewModel>(this);
    _notifier.PropertyChanged = base.PropertyChanged;
}

这会修复我的错误吗?

编辑:

PropertyChangeNotifier from link:

[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;
}

问题是,当我的MainViewModel被创建时,base.PropertyChanged是空的。构造函数被调用,字段/属性初始化(一些调用OnPropertyChanged),并在MainView.InitializeComponent()之后在base.PropertyChanged中添加处理程序(我附加了一个调试器来查看)。这个添加在ViewModelBase中完成,忽略MainViewModel中的public new event PropertyChangedEventHandler PropertyChanged

我想检查base.PropertyChanged是否被修改并复制。

我做了这个,我不知道是否有一个好主意,你认为呢?

public class ViewModelBase : INotifyPropertyChanged, IRequestClose
{
    protected event PropertyChangedEventHandler _propertyChanged;
    protected bool propertyAdded { get; private set; }
    public event PropertyChangedEventHandler PropertyChanged
    {
        add
        {
            _propertyChanged += value;
            propertyAdded = true;
        }
        remove { _propertyChanged -= value; }
    }
    protected void OnPropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = _propertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
    public Delegate[] Get_PropertyChanged()
    {
        isPropertyAdded = false;
        Delegate[] delegates = new Delegate[0];
        if (_propertyChanged != null)
        {
            delegates = _propertyChanged.GetInvocationList();
            _propertyChanged = null;
        }
        return delegates;
    }
}

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)
    {
        if (isPropertyAdded)
        {
            foreach (Delegate d in Get_PropertyChanged())
            {
                _notifier.PropertyChanged += (PropertyChangedEventHandler)d;
            }
        }
        _notifier.OnPropertyChanged(propertyName);
    }
}

对于简单的NotifyPropertyChanged("dependentProperty")来说似乎是一个令人费解的解决方案,尽管我确实理解设计奇特解决方案的愿望。如果它有一些性能/loc优势,这是有意义的,但事实并非如此。这只会增加复杂性。

相关内容

  • 没有找到相关文章

最新更新