【问题标题】:Cache public properties recalculated when DependencyProperty changes?DependencyProperty 更改时重新计算缓存公共属性?
【发布时间】: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); } }
}

我没看到的是:

  1. 如何附加到PropertyChangedEventHandler事件,使相关的非DependencyProperty属性重新计算?
  2. 如何避免使用DependencyProperty 字符串名称?
  3. DependencyProperty 工作中的OverRideMetadata 的PropertyChangedCallback 条目,但这是最好的方法吗?

【问题讨论】:

  • “我没有看到的是如何附加更改以重新计算相关的非 DependencyProperty 属性。”除非他们得到一些变化通知,否则了解变化的唯一方法是轮询。 MVVM 的整个 ViewModel 层之所以存在,是因为您并不总是控制模型,并且经常必须将其包装在您可以控制的东西中。请注意,DependancyProperties 主要用于 GUI 元素。对于后面的代码,您通常应该使用 INotifyPropertyChanged。它更简单。
  • @codebender:PropertyChangedCallbacks 是订阅依赖属性更改的最佳方式。我想我不明白你的实际问题是什么。您希望在哪里附加事件?

标签: c# wpf caching inotifypropertychanged frameworkelement


【解决方案1】:

我认为您可能正在寻找的是专门为此而设计的 CoerceValue。查一下here。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-07-31
    • 1970-01-01
    • 2014-06-08
    • 2019-07-08
    • 2016-07-21
    • 2019-06-03
    • 2019-11-09
    相关资源
    最近更新 更多