我有一个问题。我有一节课:
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元素)的总和绑定到TextBox的Text。我尝试了几个选项,但没有效果。我得到的最好的是计算我想要的东西,但只有当我打开旧版时,才将其命名为文档。当我向此文档添加新位置时,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}" />
答案 0 :(得分:3)
在WPF中的普通属性setter
中,您可以调用NotifyPropertyChanged("PropertyName")
来警告INotifyPropertyChanged
界面PropertyName
属性已更改且您想要的事实查看用户界面中的更改。
在像您这样的情况下,如果您没有财产setter
,仍需要致电NotifyPropertyChanged("PropertyName")
以查看用户界面中的更改。现在显然,你不能从setter
中调用它,因为它没有。{/ p>
通常从另一个属性setter
调用它,该属性在没有setter
的情况下在属性的输出值中起作用。例如,FirstName
属性可能在没有Initials
的{{1}}属性中使用:
setter
现在此属性只会在public string Initial
{
get { return FirstName[0].ToString(); }
}
属性更改时更改,因此调用FirstName
的合理位置将位于 属性中:
NotifyPropertyChanged("Initial")
您不必在任何属性中调用它...您也可以在更改关联值的任何地方调用它:
public string FirstName
{
get { return _firstName; }
set
{
_firstName= value;
NotifyPropertyChanged("FirstName");
NotifyPropertyChanged("Initial");
}
}
因此,无论您何时调用它,您仍需要调用FirstName = SomeObject.GetFirstName(someIdNumber);
NotifyPropertyChanged("Initial");
方法来更新UI。
答案 1 :(得分:3)
不是将所有东西混合在一起,而是需要两个类。
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
...
}
现在我们只需要在它改变时计算总和。有几次这种情况发生
让我们一次一个,我们可以通过监听构造函数中的集合更改来连接通过集合添加的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
以使项目不可变(即它们在创建后不会更改),那么您应该完成所有操作。但是,如果您需要更改Paragons,我们需要重写添加或删除项目时发生的事情
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();
}
答案 2 :(得分:1)
如果您在“ProductCount”或“PriceBertto”更改时尝试更新TotalValue,则需要通知WPF该更改。你可以尝试这样的事情:
...
public double TotalValue
{
get
{
return Math.Round (ProductCount * PriceBrutto, 2, MidpointRounding.AwayFromZero );
}
}
private int productCount = 0;
public int ProductCount
{
get
{
return productCount;
}
set
{
if( Equals( productCount, value) ) return;
productCount = value;
NotifyPropertyChange( "ProductCount" );
NotifyPropertyChange( "TotalValue" );
}
}
...
请注意,从TotalCount的setter调用NotifyPropertyChange for“TotalValue”。
我没有为你做这一切,但你也可以为你的其他财产做类似的事情。可以为影响TotalValue的其他属性执行类似的操作。