Я нашел другое, работающее решение для этой проблемы, которое я собираюсь обрисовать здесь с некоторым примером кода.Это может показаться сложным, но большая часть показанного кода представляет собой код инфраструктуры, который нужно написать только один раз.
1) Сначала определите новый атрибут, который будет использоваться для указаниязависимость между свойствами:
class DependentOnAttribute : Attribute
{
public DependentOnAttribute(string propertyName) { ... }
public string PropertyName { get { ... } }
}
2) Во-вторых, примените атрибут к зависимому свойству, например, следующим образом:
class Person : INotifyPropertyChanged
{
public DateTime DateOfBirth { get { ... }; set { ... } }
[DependentOn("DateOfBirth")]
public bool IsDateOfBirthValid { get { ... } }
public event PropertyChangedEventHandler PropertyChanged;
}
3) В-третьих, определите метод расширения на PropertyChangedEventHandler
, который будет использоваться для запуска события, рекурсивного разрешения зависимостей и запуска события для всех этих тоже:
public static void Notify(this PropertyChangedEventHandler propertyChangedEvent,
object obj, string propertyName)
{
// make sure someone is subscribed to the event:
if (propertyChangedEvent == null) return;
// raise the PropertyChanged event for the specified property:
propertyChangedEvent(obj, new PropertyChangedEventArgs(propertyName));
// find all other properties that are dependent on the specified property:
var namesOfDependentProperties = from property in obj.GetType().GetProperties()
where ... // (abbreviated for legibility)
select property.Name;
// trigger the event for all dependent properties (recursion!):
foreach (var nameOfDependentProperty in namesOfDependentProperties)
{
propertyChangedEvent.Notify(obj, nameOfDependentProperty);
}
}
Теперь PropertyChanged
событие должно быть инициировано с помощью этого метода расширения, например, для DateOfBirth
:
public DateTime DateOfBirth
{
get { ... }
set
{
...;
PropertyChanged.Notify(this, "DateOfBirth");
}
}
Это также вызовет PropertyChanged
для всех зависимых свойств.
Все это требуетнемного общей инфраструктуры (а именно, новый класс атрибутов и метод расширения), применение атрибута DependentOn
к зависимым атрибутам и вызов события PropertyChanged
с помощью метода расширения Notify
.
(Осталосьувидеть, как это решение должно быть изменено, чтобы также работать для межобъектных или подобъектных зависимостей.Я предполагаю, что требуемые изменения будут минимальными.)