【问题标题】:Capture property change using its setter使用其设置器捕获属性更改
【发布时间】:2013-01-22 10:00:33
【问题描述】:

我希望在属性更改时收到通知,以便我可以在数据库中记录该属性的旧值和新值。

所以我决定采用属性设置器的方法,并有一个处理所有属性的通用方法。

我创建了下面的类:

public class PropertyChangedExtendedEventArgs<T> : PropertyChangedEventArgs
{
    public virtual T OldValue { get; private set; }
    public virtual T NewValue { get; private set; }

    public PropertyChangedExtendedEventArgs(string propertyName,
                                            T oldValue, T newValue)
        : base(propertyName)
    {
        OldValue = oldValue;
        NewValue = newValue;

   //write to database the values!!!
    }
}

在我的财产上,我这样称呼它:

private string _surname;
public string Surname
{
    get { return _surname; }
    set 
    {
        string temp = Surname;
        _surname = value;
        Helper.PropertyChangedExtendedEventArgs("Surname", temp, value);
    }
}

但这是第一次使用泛型,所以没有什么顾虑:

  • 如何在我的财产上调用它?
  • 这是一个好方法吗?
  • 我可以在公共场合调用函数吗 PropertyChangedExtendedEventArgs(string propertyName, T oldValue, T newValue) 并保存到数据库?

【问题讨论】:

    标签: c# asp.net properties propertychanged


    【解决方案1】:

    您似乎对属性更改的使用有些困惑。
    通常,希望对其属性进行观察的组件会更改INotifyPropertyChanged 接口。因此,正确的实现类似于

    private string _surname;
    public string Surname
    {
        get { return _surname; }
        set 
        {
            if (_surname != value) // IMP: you want to inform only if value changes
            {
               string temp = Surname;
               _surname = value;
    
               // raise property change event, 
               NotifyPropertyChanged(temp, _surname);
            }
        }
    }
    

    通常,基本实现可以提供帮助实现来引发事件 - 例如,

    public abstract Component : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
    
        protected void NotifyPropertyChanged<T>(T oldVal, T newVal, [CallerMemberName] String propertyName = "")
        {
           var e = PropertyChanged;
           if (e != null)
           {
              e(this, new PropertyChangedExtendedEventArgs(propertyName, oldVal, newVal));
           }
        }
    }
    

    现在,它的消费者有责任对属性变化做出反应。这将可观察组件与不相关的对某些属性更改时要做什么的关注区分开来。通常,人们会有一些常见的实现方式——以堆叠方式保存当前对象状态,以提供撤消重做功能。

    因此,在您的情况下,您希望将它们记录到数据库(?),应该有代码可以侦听此属性更改事件并进行记录。将有一些控制器/绑定代码将遍历所有实现此接口的对象并连接事件。通常,根级别容器会执行此类内部管理 - 例如,在设计器界面中,每当创建新组件并将其添加到设计界面时,其根元素(或处理根元素的代码)都会连接事件。

    【讨论】:

    • 感谢您的回答....我唯一更改的是添加 e(this, new PropertyChangedExtendedEventArgs(propertyName, oldVal, newVal));.... 可以请为我解释一下为什么我们使用这条线?
    • @Sam1,我很抱歉,但我能理解你在问什么?该行正在引发“PropertyChanged”事件。
    • 我只是不明白为什么我们在上面的代码中检查事件是否不为空并且无法理解下一行的作用
    • @Sam1,这是引发事件的标准方式。如果没有侦听器,则需要进行空检查。临时变量e 用于确保线程安全。请参阅这篇文章 - 我正在使用LocalCopyMessenger 方法,如文章中所述:geekswithblogs.net/BlackRabbitCoder/archive/2011/12/01/…
    猜你喜欢
    • 1970-01-01
    • 2011-04-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-10
    • 2021-06-01
    • 1970-01-01
    相关资源
    最近更新 更多