【发布时间】:2018-11-14 01:19:16
【问题描述】:
我想缓存依赖于一个或多个 DependencyProperty 值的公共属性,以便它们仅在 DependencyProperty 更改时重新计算。我的类继承自FrameworkElement 和INotifyPropertyChanged。我在Implementing 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字符串名称? -
DependencyProperty工作中的OverRideMetadata的PropertyChangedCallback条目,但这是最好的方法吗?
【问题讨论】:
-
“我没有看到的是如何附加更改以重新计算相关的非 DependencyProperty 属性。”除非他们得到一些变化通知,否则了解变化的唯一方法是轮询。 MVVM 的整个 ViewModel 层之所以存在,是因为您并不总是控制模型,并且经常必须将其包装在您可以控制的东西中。请注意,DependancyProperties 主要用于 GUI 元素。对于后面的代码,您通常应该使用 INotifyPropertyChanged。它更简单。
-
@codebender:PropertyChangedCallbacks 是订阅依赖属性更改的最佳方式。我想我不明白你的实际问题是什么。您希望在哪里附加事件?
标签: c# wpf caching inotifypropertychanged frameworkelement