【问题标题】:NotifyPropertyChanged of a Calculated property when Items in List Changes列表中的项目更改时计算属性的 NotifyPropertyChanged
【发布时间】:2023-03-14 16:46:01
【问题描述】:

我有一个如下的模型 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;
    }
}

此计算属性返回所有发票的余额总和(如果发票的 Use 属性为 true)。使用网格中的复选框在视图上将 Use 属性选择为 true。

现在...问题是:当 SupplierInvoice 模型的 Use 属性已更改时,我如何通知此计算属性 (ApTotal) 的 PropertyChanged?

【问题讨论】:

    标签: c# wpf mvvm inotifypropertychanged


    【解决方案1】:

    我认为用ObservableCollection&lt;TObject&gt; 替换您的List&lt;TObject&gt; 就可以了。

    据我所知,List 没有将 PropertyChangedEvent 传播到 UI 线程。

    【讨论】:

    • 我在模型中实现了 INotifyPropertyChanged 并在 Use 属性上使用了 NotifyPropertyChanged 但这并不能解决问题。我需要通知 UI ApTotal 已更改,因为在列表中选择或取消选择了 Use 属性
    • 您是否在 xaml 视图中使用双向绑定?
    • 我没有在 ApTotal 上使用双向,因为它是只读的,因此双向不起作用。但是,在 SupplierInvoice 的 Use 属性中,列表由我确实使用 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");
              }
          }
      }
      

      【讨论】:

      • 感谢您的回答。但是,这不起作用,因为供应商发票列表仅更改一次。列表组成的类 SupplierInvoice 中的 Use 属性不断变化
      • 这没什么区别。您的解决方案是在您重新计算 ApTotal 属性时调用 this.RaisePropertyChanged("ApTotal");
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-05-04
      • 1970-01-01
      • 1970-01-01
      • 2020-08-08
      • 1970-01-01
      • 2016-03-03
      • 2013-03-02
      相关资源
      最近更新 更多