简体   繁体   中英

C# - Automatically update object property when other properties are modified

I would like to be able to automatically update the value of the UpdateDate field to current datetime only if certain other properties are modified. For this example - Title. What is a possible way of doing this if a class was to contain dozens of properties, of which half should trigger the UpdateDate value change?

    public class Ticket
    {
       public Ticket() { }

       public int TicketID { get; set; }
       public string Title { get; set; }
       public string Description { get; set; }
       public DateTime UpdateDate { get; set; }
    }

No need to use INotifyPropertyChanged. Here's an example where if the "Title" property changes, the UpdateDate will be set to "DateTime.Now"

public class Ticket
{
   public int TicketID { get; set; }
   private string title;
   public string Title
   {
        get { return title; }
        set
        {                
            title = value;
            UpdateDate = DateTime.Now;
        }
    }
    public string Description { get; set; }
    public DateTime UpdateDate { get; set; }   
}

您仍然需要为每个属性编写一些 goo 代码,但INotifyPropertyChanged 接口为此提供了一个模式。

Just Create a base class which inherits from INotifyPropertyChanged interface like this:

public abstract class BaseViewModel : INotifyPropertyChanged
{
    #region members
    protected IUnitOfWork UnitOfWork;
    #endregion

    public BaseViewModel()
    {            
    }

     //basic ViewModelBase
    internal void RaisePropertyChanged(string prop)
    {
        if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(prop)); }
    }
    public event PropertyChangedEventHandler PropertyChanged;

}

then you can use in your concrete class like this:

public class TransactionItemViewModel : BaseViewModel
{
    int _Quantity;
    public int Quantity
    {
        get
        {
            return _Quantity;
        }
        set
        {
            if (_Quantity != value)
            {
                _Quantity = value;
                RaisePropertyChanged("Quantity");
                RaisePropertyChanged("TotalSalePrice");
            }
        }
    }

    public decimal TotalSalePrice
    {
        get
        {                                
            return 100 * Quantity;
        }
    }
}

I see this is an old question, but after searching for the same answer I came up with a relatively clean (but not totally automatic) solution.

You can create two classes to help you with this. The first is Recorder which just keeps and updates the DateTime:

public class Recorder {
    public Recorder(DateTime updateDate) {
        UpdateDate = updateDate;
    }

    public void Update() {
        UpdateDate = DateTime.Now;
    }

    public DateTime UpdateDate { get; private set; }
}

Then, Recorded<T> which will update a Recorder when its value is changed:

public class Recorded<T> {
    private readonly Recorder recorder;
    private T value;

    public Recorded(Recorder recorder, T value = default(T)) {
        this.recorder = recorder;
        this.value = value;
    }

    public T Value {
        get => value;
        set {
            this.value = value;
            recorder.Update();
        }
    }
}

Your original Ticket would require some changes, but could be implemented like this:

public class Ticket
{
   private readonly Recorder recorder;
   private readonly Recorded<int> ticketId;
   private readonly Recorded<string> title;
   private readonly Recorded<string> description;

   public Ticket(int ticketId, string title, string description, DateTime updateDate)
   {
       recorder = new Recorder(updateDate);
       this.ticketId = new Recorded<int>(recorder, ticketId);
       this.title = new Recorded<string>(recorder, title);
       this.description = new Recorded<string>(recorder, description);
   }

   public int TicketID { get => ticketId.Value; set => ticketId.Value = value; }
   public string Title { get => title.Value; set => title.Value = value; }
   public string Description { get => description.Value; set => description.Value = value; }
   public DateTime UpdateDate { get => recorder.UpdateDate; }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM