I want to cache public properties that depend on one or more DependencyProperty values, such that they only get recalculated when the DependencyProperty changes. My class inherits from FrameworkElement and INotifyPropertyChanged. I've followed some portions the answer here Implementing INotifyPropertyChanged. Simplified class:
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); } }
}
What I didn't see is:
- How to attach to
PropertyChangedEventHandlerevents, so related nonDependencyPropertyproperties to be recalculated? - How to avoid use of
DependencyPropertystring names? PropertyChangedCallbackentries forOverRideMetadataof theDependencyPropertywork, but is that the best way?