c# - 将 TextBox 的文本绑定(bind)到 list<T> 值的总和

标签 c# wpf binding observablecollection inotifypropertychanged

我有一个问题。我有一个类:

public class ParagonClass : INotifyPropertyChanged
{
    //some variables
    private decimal _totalValue;

    public static ObservableCollection<ParagonClass> paragonLista { get; set; }

    public decimal TotalValue
    {
        get
        {
            if (ProductID > 0)
                _totalValue = Math.Round(ProductCount * PriceBrutto, 2, MidpointRounding.AwayFromZero);
            return _totalValue;
        }
        set
        {
            _totalValue = value;
            NotifyPropertyChanged("TotalValue");
        }
    }

    ...
}

在我的窗口中,我想将 TotalValue 的总和(所有 paragonLista 元素的)绑定(bind)到 TextBox 的文本。我尝试了几个选项但没有效果。我得到的最好的是计算我想要的,但只有当我打开旧文件时,才将其命名为文档。当我向该文档添加新位置时,TextBox 中的值没有改变。我通过以下方式实现了这一目标:

 private decimal _Sum;
 public decimal Sum
 {
     get
     {
         _Sum = ParagonClass.paragonLista.Sum(x => x.TotalValue);
         return _Sum;
     }
 }

在 .xaml 中:

<TextBox Name="priceTextBox" FontSize="28" Margin="0,0,5,0" HorizontalAlignment="Right" Text="{Binding Sum, UpdateSourceTrigger=PropertyChanged}" />

最佳答案

您不需要将所有内容混合在一起,而是需要两个类。

public class ParagonClass : INotifyPropertyChanged
{
  //some variables
  private decimal _totalValue;

  public decimal TotalValue
  {
    get
    {
        if (ProductID > 0)
            _totalValue = Math.Round(ProductCount * PriceBrutto, 2, MidpointRounding.AwayFromZero);
        return _totalValue;
    }
  // No need for a setter if its calculated
  // See Sheridan's answer for how to do this
  //       set
  //       {
  //           _totalValue = value;
  //           NotifyPropertyChanged("TotalValue");
  //       }
  }

  ...
}

还有一个集合

public class ParagonCollection : ObservableCollection<ParagonClass>, INotifyPropertyChanged
{
  private int sum;
  public int Sum
  { 
    get{ return sum;} 
    set
    {
      sum = value;
      NotifyPropertyChanged("Sum");
    }
 }
  // You'll need as implantation of INotifyPropertyChanged here
  // and some extra stuff to come
  ...
}

现在我们只需要在它发生变化时计算总和。多次出现这种情况

  1. 当一个新的 Paragon 添加到收藏中时
  2. 当 Paragon 改变时

让我们一次一个地处理它们,我们可以通过监听构造函数中的集合变化来连接通过集合添加的 Paragon 项目

public ParagonCollection()
{
   // When the collection changes set the Sum to the new Sum of TotalValues
   this.CollectionChanged += OnCollectionChanged;
}

private void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs notifyCollectionChangedEventArgs)
{
  Recalculate();
}

private void Recalculate()
{
  Sum = this.Sum(x=>x.TotalValue);
}

现在,如果您设计您的 ParagonClass 以便项目是不可变的(即它们在创建后不会更改),那么您应该完成所有工作。但是,如果您需要更改您的 Paragon,我们需要重写添加或删除项目时发生的事情

private void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs args)
{
  foreach(ParagonClass item in args.OldItems)
  {
    // Unsubscribe to changes in each item
    item.PropertyChanged -= OnItemChanged;
  }
  foreach(ParagonClass item in args.NewItems)
  {
    // Subscribe to future changes for each item
    item.PropertyChanged += OnItemChanged;
  }

  Recalculate();
}

private void OnItemChanged(object sender, PropertyChangedEventArgs args)
{
  Recalulate();

  // You might decide that you only want to recalculate for some property 
  // changes, and do something like the following instead
  // if (args.PropertyName=="TotalValue")
  //   Recalulate();
}

关于c# - 将 TextBox 的文本绑定(bind)到 list<T> 值的总和,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21119268/

相关文章:

c# - 使用 WCF 在客户端中获取签名的 SOAP 消息

c# - 喜欢页面时,Azure ACS Facebook 错误 191 redirect_uri 不属于应用程序

c# - 无法在 LINQ 查询中将类型 'System.DateTime?' 隐式转换为 'System.DateTime'

wpf - 使用 Task 与 Dispatcher 进行 ui 线程操作

ios - Swift 中的可选绑定(bind)在prepareForSegue 中不起作用

c# - 如果有更多方法,C#类是否会占用更多空间?

c# - 如何在 ItemsControl 中绑定(bind) DataTemplate

c# - 重构 PropertyChangedEventHandler

wpf - 与 ListView ItemTemplate 中的静态属性绑定(bind)

java - 需要从绑定(bind)文件在 package-info.java 中生成 JAXB 注释