属性更改后更新XAML绑定

时间:2014-12-01 00:56:28

标签: xaml data-binding windows-8.1 mvvm-light

我在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等?

3 个答案:

答案 0 :(得分:1)

非常简单:

为每个集合注册ObservableCollection<T>.CollectionChanged事件。由于您所需的属性基于对集合的某些计算。

On event fire在这些属性上提升OnPropertyChanged。


如何引发OnPropertyChanged / inotifypropertychanged

的示例

MSDN: inotifypropertychanged Example

答案 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");
    }