NotifyPropertyChanged вычисляемого свойства при изменении элементов в списке

#c# #wpf #mvvm #inotifypropertychanged

#c# #wpf #mvvm #inotifypropertychanged

Вопрос:

У меня есть model SupplierInvoice следующим образом:

 public class SupplierInvoice
{
    public bool Use { get; set; }
    public ApInvoice Invoice { get; set; }
}
  

И ViewModel со списком этой модели:

 private List<SupplierInvoice> _SupplierInvoices;
public List<SupplierInvoice> SupplierInvoices
{
    get
    {
        return this._SupplierInvoices;
    }
    set
    {
        if (this._SupplierInvoices != value)
        {
            this._SupplierInvoices = value;
            this.RaisePropertyChanged("SupplierInvoices");
        }
    }
}
  

в этой ViewModel у меня тоже есть вычисляемое свойство:

 public decimal ApTotal
{
    get
    {
        decimal total = 0;

        if (this.SupplierInvoices != null)
        {
            foreach (SupplierInvoice invoice in this.SupplierInvoices)
            {
                if (invoice.Use)
                {
                    total  = invoice.Invoice.MthInvBal1;
                }
            }
        }

        return total;
    }
}
  

это вычисляемое свойство возвращает сумму остатка по всем счетам (если свойство использования счета имеет значение true). Свойство Use выбрано как true в представлении с флажком в сетке.

Теперь … вопрос в следующем: как мне NotifyPropertyChanged этого вычисляемого свойства (ApTotal), когда свойство Use модели SupplierInvoice было изменено?

Ответ №1:

Я думаю, что замена вашего List<TObject> на an ObservableCollection<TObject> поможет.

Из того, что я помню List , не распространяется PropertyChangedEvent на поток пользовательского интерфейса.

Комментарии:

1. Я реализовал INotifyPropertyChanged в модели и также использовал NotifyPropertyChanged в свойстве Use, однако это не решает проблему. Мне нужно уведомить пользовательский интерфейс о том, что ApTotal изменился с тех пор, как свойство Use было выбрано или отменено в списке

2. Используете ли вы двустороннюю привязку в своем представлении xaml?

3. Я не использую two way для ApTotal, поскольку он доступен только для чтения, и поэтому twoway не будет работать. Однако в свойстве использования SupplierInvoice список состоит из я использую TwoWay

Ответ №2:

Это может быть немного непослушным, но вы всегда можете это сделать:

 private List<SupplierInvoice> _SupplierInvoices;
public List<SupplierInvoice> SupplierInvoices
{
    get
    {
        return this._SupplierInvoices;
    }
    set
    {
        if (this._SupplierInvoices != value)
        {
            this._SupplierInvoices = value;
            this.RaisePropertyChanged("SupplierInvoices");
            this.RaisePropertyChanged("ApTotal");
        }
    }
}
  

Ответ №3:

Всякий раз, когда у вас есть вычисляемое свойство, вам просто нужно вызвать INotifyPropertyChanged.PropertyChanged событие из других свойств, которые участвуют в вычислении. Так как ваше ApTotal свойство вычисляется только из SupplierInvoices свойства, то вы можете просто уведомить интерфейс из этого установщика свойств:

 public List<SupplierInvoice> SupplierInvoices
{
    get
    {
        return this._SupplierInvoices;
    }
    set
    {
        if (this._SupplierInvoices != value)
        {
            this._SupplierInvoices = value;
            this.RaisePropertyChanged("SupplierInvoices");
            this.RaisePropertyChanged("ApTotal");
        }
    }
}
  

Комментарии:

1. Спасибо за ответ. Однако это не работает, поскольку список счетов-фактур поставщика изменяется только один раз. Это свойство, используемое в классе SupplierInvoice, из которого состоит список, который постоянно меняется

2. Это мало что меняет. Ваше решение заключается в том, чтобы вызывать this.RaisePropertyChanged("ApTotal"); его всякий раз, когда вы пересчитываете ApTotal свойство.