#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
свойство.