Я хочу кэшировать общедоступные свойства, которые зависят от одного или нескольких значений DependencyProperty
, так что они пересчитываются только при изменении DependencyProperty
.Мой класс наследует от FrameworkElement
и INotifyPropertyChanged
.Я следовал за некоторыми частями ответа здесь Реализация INotifyPropertyChanged .Упрощенный класс:
public class ElementBase : FrameworkElement, INotifyPropertyChanged {
static ElementBase() {
WidthProperty.OverrideMetadata(typeof(ElementBase), new FrameworkPropertyMetadata(new PropertyChangedCallback(OnCalculatedValueChanged)));
HeightProperty.OverrideMetadata(typeof(ElementBase), new FrameworkPropertyMetadata(new PropertyChangedCallback(OnCalculatedValueChanged)));
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string propertyName = null) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
private static void OnCalculatedValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
// how can property's string name be avoided
switch (e.Property.ToString()) { // force update of non-dependency properties
case "Height": // is there a better way to force the recalculations?
((ElementBase)d).HalfHeight = 0.0; // set overwrites with calculated value
((ElementBase)d).Center = new Point(0, 0); // set overwrites with calculated value
break;
case "Width":
((ElementBase)d).HalfWidth = 0.0; // set overwrites with calculated value
((ElementBase)d).Center = new Point(0, 0); // set overwrites with calculated value
break;
default: break;
}
}
// Caching of the public properties.
private double halfWidth; // cached calculated half width
public double HalfWidth { get => halfWidth; set { halfWidth = Width / 2.0; } }
private double halfHeight; // cached calculated half height
public double HalfHeight { get => halfHeight; set { halfHeight = Height / 2.0; } }
private Point center; // cached calculated center point
public Point Center { get => center; set { center = new Point(HalfWidth, HalfHeight); } }
}
То, что я не видел, это:
- Как прикрепить к
PropertyChangedEventHandler
событиям, поэтому необходимо пересчитать связанные не DependencyProperty
свойства? - Как избежать использования
DependencyProperty
имен строк? PropertyChangedCallback
записей для OverRideMetadata
работы DependencyProperty
, но лучше ли это?