使用设置器捕获属性更改

本文关键字:属性 设置 | 更新日期: 2023-09-27 17:54:57

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

所以我决定用属性setter的方法,用一个通用的方法来处理所有的属性。

我创建了下面的class:

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)并保存到数据库?

使用设置器捕获属性更改

你似乎对属性更改的用法有点困惑。
通常情况下,组件希望其属性的可观察性改变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));
       }
    }
}

现在,消费者的责任在于如何应对财产变化。这样就把可观察组件从一些属性改变时该怎么做的无关问题中分离出来了。通常,会有一些常见的实现会说——以堆叠的方式保存当前对象状态,以提供撤销-重做功能。

因此,在您的情况下,您希望将它们记录到数据库(?),应该有代码来侦听这个属性更改事件并进行日志记录。将会有一些控制器/绑定代码迭代实现该接口的所有对象并连接事件。通常,根级容器做这样的家务——例如,在设计器图面中,每当创建新组件并将其添加到设计图面中时,它的根元素(或处理根元素的代码)将连接事件。