我在Windows 8.1 Store应用程序上使用MVVM指示灯。我有一个视图模型,它有几个没有setter的属性(它们的值来自不同的属性)。这是我的ViewModel的一部分:
public float TotalAmount
{
get
{
if (!LineItems.Any())
return 0.0f;
return SubTotal + TotalFees - TotalDiscounts;
}
}
public float SubTotal
{
get
{
return !LineItems.Any() ? 0.0f : LineItems.Select(i => i.Price.Amount).Sum();
}
}
public float TotalFees
{
get
{
return !Fees.Any() ? 0.0f : Fees.Select(f => f.Amount).Sum();
}
}
public float TotalDiscounts
{
get
{
return !Discounts.Any() ? 0.0f : Discounts.Select(d => d.Amount).Sum();
}
}
public ObservableCollection<Discount> Discounts { get; set; }
public ObservableCollection<Fee> Fees { get; set; }
public Customer Customer { get; set; }
public ObservableCollection<OrderLineItem> LineItems { get; set; }
在XAML中,我绑定到每个属性,并希望在将Item添加到LineItems时更新它们。
以下是XAML的相关部分:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="3*" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<TextBlock Text="SubTotal:" Style="{StaticResource OrderDetailsLabel}" />
<TextBlock Grid.Column="1" Style="{StaticResource OrderDetailsValue}"
Text="{Binding SubTotal, Converter={StaticResource MoneyConverter}, Mode=TwoWay}" />
<TextBlock Grid.Row="1" Text="Fees:" Style="{StaticResource OrderDetailsLabel}" />
<TextBlock Grid.Row="1" Style="{StaticResource OrderDetailsValue}" Grid.Column="1"
Text="{Binding TotalFees, Converter={StaticResource MoneyConverter}, Mode=TwoWay}" />
<TextBlock Grid.Row="2" Text="Discounts:" Style="{StaticResource OrderDetailsLabel}" />
<TextBlock Grid.Row="2" Style="{StaticResource OrderDetailsValue}" Grid.Column="1"
Text="{Binding TotalDiscounts, Converter={StaticResource MoneyConverter}, Mode=TwoWay}" />
<TextBlock Grid.Row="3" Text="Order Total:" Style="{StaticResource OrderDetailsLabel}" />
<TextBlock Grid.Row="3" Style="{StaticResource OrderDetailsValue}" Grid.Column="1"
Text="{Binding TotalAmount, Converter={StaticResource MoneyConverter}, Mode=TwoWay}" />
</Grid>
My Binding to LineItems正在按预期工作,但是通过对订单项进行数学运算填充的字段不是。
订单项绑定按预期运行:
<ListView ItemsSource="{Binding LineItems, Mode=TwoWay}"
SelectionMode="Single"
HorizontalAlignment="Stretch">
<ListView.ItemContainerStyle>
....
如何在LineItems更改时更新SubTotal,Total等?
答案 0 :(得分:1)
非常简单:
为每个集合注册ObservableCollection<T>.CollectionChanged
事件。由于您所需的属性基于对集合的某些计算。
On event fire在这些属性上提升OnPropertyChanged。
如何引发OnPropertyChanged / inotifypropertychanged
的示例答案 1 :(得分:1)
你的构造函数中有这样的东西:
LineItems.CollectionChanged += (s, e) =>
{
RaisePropertyChanged("SubTotal");
RaisePropertyChanged("TotalFees");
RaisePropertyChanged("TotalDiscounts");
}
假设您的ViewModel实现了INotifyPropertyChanged,并且有一个&#39; RaisePropertyChanged&#39;引发PropertyChanged事件的方法(例如,您使用MVVM-Light的ViewModelBase作为基类)。
答案 2 :(得分:0)
我最后通过在AddLineItems消息的处理程序中启动OnPropertyChanged事件来解决这个问题:
public NewOrderViewModel()
{
//Subscribe to messages
MessengerInstance.Register<OrderItemAdded>(this, o => AddOrderItem(o.LineItem));
MessengerInstance.Register<SelectedCustomer>(this, c => Customer = c.Customer);
Discounts = new ObservableCollection<Discount>();
Fees = new ObservableCollection<Fee>();
LineItems = new ObservableCollection<OrderLineItem>();
}
private void AddOrderItem(OrderLineItem lineItem)
{
//add Line Item to collection
LineItems.Add(lineItem);
//Raise events for properties derived from collection
RaisePropertyChanged("TotalAmount");
RaisePropertyChanged("SubTotal");
}