INotifyPropertyChanged 和静态属性 [英] INotifyPropertyChanged and static properties

查看:34
本文介绍了INotifyPropertyChanged 和静态属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我因一个简单的问题而束手无策.我有一个实现 INotifyPropertyChanged 的类.某些实例属性的 getter 使用静态属性,因此如果静态属性更改,它们的值可能会更改?这是一个简化的示例.

I'm tying myself in knots over a simple problem. I have a class that implements INotifyPropertyChanged. Some of the instance properties' getters use static properties and thus their values may change if the static property changes? Here's a simplified example.

class ExampleClass : INotifyPropertyChanged
{

    private static int _MinimumLength = 5;
    public static int MinimumLength
    {
        get
        {
            return _MinimumLength;
        }
        set
        {
            if (_MinimumLength != value)
            {
                _MinimumLength = value;
                //WHAT GOES HERE
            }
        }
    }

    private int _length = -1;
    public int length
    {
        get
        {
            return (_length > _MinimumLength) ? _length : _MinimumLength;
        }
        set
        {
            var oldValue = (_length > _MinimumLength) ? _length : _MinimumLength;
            if (_length != value)
            {
                _length = value;
                var newValue = (_length > _MinimumLength) ? _length : _MinimumLength;
                if (newValue != oldValue)
                {
                    OnPropertyChanged("length");
                }
            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    [NotifyPropertyChangedInvocator]
    protected virtual void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

}

显然,如果静态属性 MinimumLength 发生变化,那么每个实例的属性 length 也可能发生变化.但是静态属性应该如何表示实例可能发生的变化呢?它不能调用 OnPropertyChanged,因为它不是静态的.

Clearly if the static property MinimumLength changes then every instance's property length may also change. But how should the static property signal the possible change to the instances? It cannot call OnPropertyChanged since that is not static.

我可以在所有实例的类级别保留一个列表,并对每个实例调用一个方法,但不知何故,这感觉有点矫枉过正.或者我可以将静态属性提取到一个单例类中,但从逻辑上讲,它们存在于类级别.对此是否有既定的模式,或者我应该以不同的方式思考这个问题?

I could keep a list at the class level of all the instances and call a method on each one, but somehow that feels like overkill. Or I could pull the static properties out into a singleton class but logically they live at the class level. Is there an established pattern for this or should I be thinking about this differently?

推荐答案

如果您倾向于保持该设计,那么我会采用如下解决方案:

If you're inclined to maintain that design then I would go with a solution like the following:

public static int MinimumLength
{
    get { return _MinimumLength; }
    set
    {
        if (_MinimumLength != value)
        {
            _MinimumLength = value;
            OnGlobalPropertyChanged("MinimumLength");
        }
    }
}
static event PropertyChangedEventHandler GlobalPropertyChanged = delegate { };
static void OnGlobalPropertyChanged(string propertyName)
{
    GlobalPropertyChanged(
        typeof (ExampleClass), 
        new PropertyChangedEventArgs(propertyName));
}
public ExampleClass()
{
    // This should use a weak event handler instead of normal handler
    GlobalPropertyChanged += this.HandleGlobalPropertyChanged;
}
void HandleGlobalPropertyChanged(object sender, PropertyChangedEventArgs e)
{
    switch (e.PropertyName)
    {
        case "MinimumLength":
            if (length > MinimumLength)
                length = MinimumLength;
            break;
    }
}

这几乎等同于维护一个实例列表,但我发现它更易于维护和更清晰.此外,您确实需要使用弱事件处理程序策略,否则您的实例将不会被垃圾回收,因为它们将始终与充当 GC 根的静态事件相关联.

This is pretty much equivalent to maintaining a list of instances but I find it more maintainable and clearer. Also, you really need to use a weak event handler strategy, otherwise, your instances will not be garbage collected because they will always be associated with the static event which acts like a GC root.

您可以在以下博客文章(由我撰写,因此我有偏见)中阅读有关弱事件处理程序的更多信息:

You can read more about weak event handlers in the following blog posts (which were written by me so I'm biased):

.NET 弱事件处理程序 - 第一部分

.NET 弱事件处理程序 - 第一部分

在一个不相关的注释中,您的代码当前触发了属性更改,而实际上属性值没有更改.例如:

In an unrelated note your code is currently firing property changed when in fact the property value did not change. For example:

  1. 将最小长度设置为 5;
  2. 设置长度为10;(事件触发,因为值从默认值 0 更改为 5)
  3. 设置长度为11;(事件触发但不应该,因为长度仍然是 5)

这篇关于INotifyPropertyChanged 和静态属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆