Я разрабатываю приложение в C# WPF.Копировать EventHandler в унаследованном классе
Я использую класс 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 Безразлично» t обновить (без использования PropertyChangedNotifier он работает). Я видел, что система инициирует окна с помощью WindowsBase.dll!System.ComponentModel.PropertyChangedEventManager.StartListening(object source)
, а затем я увидел, что мой ViewModelBase.PropertyChanged не имеет значения null, когда вызывается конструктор для MainViewModel.
Можно ли сделать что-то вроде этого:
public MainViewModel()
{
_notifier = new PropertyChangedNotifier<MainViewModel>(this);
_notifier.PropertyChanged = base.PropertyChanged;
}
И будет, что исправить мою ошибку?
Edit:
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'? Почему бы просто не реализовать «INotifyPropertyChanged» правильно? –
@ LasseV.Karlsen Особенно, когда он * уже реализован наследованием от ViewModelBase. ИМО, вопрос не имеет смысла. – Clemens
@Clemens: Правильно –